Python Forum
TypeError: string indices must be integers
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TypeError: string indices must be integers
#1
given the code snippet:
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {key['question']}")
Line 5 fails with the error code,
Error:
TypeError: string indices must be integers
The variable named 'i' is clearly an integer. Can someone explain why it fails with this error?
Yoriz write Aug-30-2022, 02:04 PM:
Please post all code, output and errors (in their entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
Why do you assume the problem is with i?

The error message talks about an index - i isn't being used as an index. However, 'question' is, so it looks like
Output:
key
is a string.

In cases like this, if it isn't at first glance obvious where the error is coming from, break down the expression into several parts. That way, the error will come from a more specific place.
Reply
#3
There is not need need(a bad way) to make a varibale i at start an use it at index later.
Just loop over the dictionary like this.
quiz = {
    'What is the fastest land animal?': 'Cheetah',
    'What is Pi?': 3.14
    }

for key, value in quiz.items():
    #print(key, value)
    print(f"Question {key} answer is: {value}")
Output:
Question What is the fastest land animal? answer is: Cheetah Question What is Pi? answer is: 3.14
Reply
#4
(Aug-30-2022, 02:17 PM)ndc85430 Wrote: Why do you assume the problem is with i?

The error message talks about an index - i isn't being used as an index. However, 'question' is, so it looks like
Output:
key
is a string.

In cases like this, if it isn't at first glance obvious where the error is coming from, break down the expression into several parts. That way, the error will come from a more specific place.


You were absolutely right. It wasn't referring to the i but to 'question'. The fact is, there is no key in the dictionary by the name of 'question', but rather a value does. So all I needed to do was change key to value and it worked beautifully.
Reply
#5
for i, value in enumerate(quiz.values()):
    print(f"Question {i+1} : {value}")
Reply
#6
(Aug-30-2022, 01:02 PM)JonWayn Wrote: given the code snippet:
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {key['question']}")
Line 5 fails with the error code,
Error:
TypeError: string indices must be integers
The variable named 'i' is clearly an integer. Can someone explain why it fails with this error?

full code:
quiz = {
    "question1": {
        "question": "What is the capital of France?",
        "answer": "Paris"
    },
    "question2": {
        "question": "What is the capital of Germany?",
        "answer": "Berlin"
    },
    "question3": {
        "question": "What is the capital of Italy?",
        "answer": "Rome"
    },
    "question4": {
        "question": "What is the capital of England?",
        "answer": "London"
    },
    "question5": {
         "question": "What is the capital of Norway?",
        "answer": "Oslo"
    },
    "question6": {
        "question": "What is the capital of Switzerland?",
        "answer": "Bern"
    },
    "question7": {
        "question": "What is the capital of Austria?",
        "answer": "Vienna"
    },
    "question8": {
        "question": "What is the capital of Spain?",
        "answer": "Madrid"
    },
    "question9": {
        "question": "What is the capital of Portugal?",
        "answer": "Lisbon"
    },
    "question10": {
        "question": "What is the capital of Belgium?",
        "answer": "Brussels"
    },
    "question11": {
        "question": "What is the capital of Sweden?",
        "answer": "Stockholm"
    },
    "question12": {
        "question": "What is the capital of Denmark?",
        "answer": "Copenhagen"
    },
    "question6": {
        "question": "What is the capital of Holland?",
        "answer": "Amsterdam"
    },
}

score = 0
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {value['question']}")
    answer = input("Answer? ")

    if answer.lower() == value['answer'].lower():
        score += 1
        print('Correct!')
    else:
        print("Incorrect :{")
        print("The correct answer is: " + value['answer'])

    print(f"Your score is {score}")
Error:
TypeError: string indices must be integers
I did get it resolved with the help of another reply but thank you for pointing me to the proper usage of the interface. It's pretty awesome
Reply
#7
Some advice can simplify the dictionary be using enumerate() then no need to hardcode Question1,Question2....,
then also can remove i = 0.
Also if using function it look cleaner.
Example.
def questions():
   return {
       "What is the capital of France?": 'Paris',
       "What is the capital of Germany? ": 'Berlin',
     }

def quiz(questions):
    score = 0
    for quiz_numb, question in enumerate(questions.keys(), 1):
        answer = input(f'Question.{quiz_numb}\n{question} ')
        if questions[question] == answer:
            print('Correct\n')
            score += 1
        else:
            print(f'Incorrect the answer was: {questions[question]}\n')
    print(f'Total score for this round: {score}')

if __name__ == '__main__':
   quiz(questions())
Output:
Question.1 What is the capital of France? Paris Correct Question.2 What is the capital of Germany? Bern Incorrect the answer was: Berlin Total score for this round: 1
Reply
#8
Dictionaries are not a good choice for your quiz. I can accept this as a dictionary:
{
        "question": "What is the capital of France?",
        "answer": "Paris"
    }
But this should be a list.
quiz = {
    "question1": {},
    "question2": {},
    ...
}
Using "questionN" keys just makes it more difficult to access the questions, and forced you to use items().

I would not use dictionaries for either the questions or the quiz. Since neither the question or quiz change I used tuples.
quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
 
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
 
print(f"Your score is {score}")
Reply
#9
(Aug-30-2022, 05:48 PM)deanhystad Wrote: Dictionaries are not a good choice for your quiz. I can accept this as a dictionary:
{
        "question": "What is the capital of France?",
        "answer": "Paris"
    }
But this should be a list.
quiz = {
    "question1": {},
    "question2": {},
    ...
}
Using "questionN" keys just makes it more difficult to access the questions, and forced you to use items().

I would not use dictionaries for either the questions or the quiz. Since neither the question or quiz change I used tuples.
quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
 
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
 
print(f"Your score is {score}")


Thank you. I like the brevity of code that you implement but I will have to wrap my mind around the logic of its elegance and simplicity
Reply
#10
This code:

quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
  
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
  
print(f"Your score is {score}")
...even with a correction to the syntax (a missing comma in the nested tuple), I can't see how it's going to work.

If I change the code to this:

quiz = (
    ("What is the capital of France?", "PARIS"),
    ("What is the capital of Germany?", "BERLIN")
)
  
score = 0
for index, question in enumerate(quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
  
print(f"Your score is {score}"))
... then yes, it works fine, and is a nice, simple way to do this.
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  tuple indices must be integers or slices, not str cybertooth 16 11,637 Nov-02-2023, 01:20 PM
Last Post: brewer32
  No matter what I do I get back "List indices must be integers or slices, not list" Radical 4 1,190 Sep-24-2023, 05:03 AM
Last Post: deanhystad
  boto3 - Error - TypeError: string indices must be integers kpatil 7 1,288 Jun-09-2023, 06:56 PM
Last Post: kpatil
  Response.json list indices must be integers or slices, not str [SOLVED] AlphaInc 4 6,451 Mar-24-2023, 08:34 AM
Last Post: fullytotal
  "TypeError: string indices must be integers, not 'str'" while not using any indices bul1t 2 2,052 Feb-11-2023, 07:03 PM
Last Post: deanhystad
  Error "list indices must be integers or slices, not str" dee 2 1,476 Dec-30-2022, 05:38 PM
Last Post: dee
  TypeError: float() argument must be a string or a number, not 'list' Anldra12 2 4,894 Jul-01-2022, 01:23 PM
Last Post: deanhystad
  TypeError: list indices must be integers or slices, not range Anldra12 2 2,594 Apr-22-2022, 10:56 AM
Last Post: Anldra12
  string indices must be integers when parsing Json ilknurg 3 6,404 Mar-10-2022, 11:02 AM
Last Post: DeaD_EyE
  TypeError: not enough arguments for format string MaartenRo 6 2,953 Jan-09-2022, 06:46 PM
Last Post: ibreeden

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020