Словарь меняется без видимой причины - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь создать игру по пустякам из соображений обучения, но с моим словарем происходит нечто странное, чего я не могу понять.

Код, который я обычно тестировал, чтобы увидеть, как все это работает, таков:

cat = {
    'easy': {
        'books': 'https://opentdb.com/api.php?amount=50&category=10&difficulty=easy&type=boolean',
        'films': 'https://opentdb.com/api.php?amount=50&category=11&difficulty=easy&type=boolean',
        'general knowledge': 'https://opentdb.com/api.php?amount=50&category=9&difficulty=easy&type=boolean',
        'music': 'https://opentdb.com/api.php?amount=50&category=12&difficulty=easy&type=boolean',
        'science & nature': 'https://opentdb.com/api.php?amount=50&category=17&difficulty=easy&type=boolean',
        'sports': 'https://opentdb.com/api.php?amount=50&category=21&difficulty=easy&type=boolean'
    },
    'medium': {
        'books': 'https://opentdb.com/api.php?amount=50&category=10&difficulty=medium&type=boolean',
        'films': 'https://opentdb.com/api.php?amount=50&category=11&difficulty=medium&type=boolean',
        'general knowledge': 'https://opentdb.com/api.php?amount=50&category=9&difficulty=medium&type=boolean',
        'music': 'https://opentdb.com/api.php?amount=50&category=12&difficulty=medium&type=boolean',
        'science & nature': 'https://opentdb.com/api.php?amount=50&category=17&difficulty=medium&type=boolean',
        'sports': 'https://opentdb.com/api.php?amount=50&category=21&difficulty=medium&type=boolean'
    }
}

print(cat)

for level in cat:
    print(level)

catselect = []
while catselect not in ("1", "2"):
    catselect = input("Select a category, for easy press 1, for medium press 2: ")

    if catselect == "1":
        selectedcat = "easy"
    elif catselect == "2":
        selectedcat = "medium"
    print(f"You selected the {selectedcat} difficulty level")

    print("The subjects can be: ")
    for i, cat[selectedcat] in enumerate(cat[selectedcat]):
        print(i, cat[selectedcat])

print(cat)

Так что, когда код запускается, код словаря cat больше не совпадает, и я не понимаю У меня нет никаких причин, по которым это может произойти.

Вот что я вижу:

{'easy': {'books': 'https://opentdb.com/api.php?amount=50&category=10&difficulty=easy&type=boolean', 'films': 'https://opentdb.com/api.php?amount=50&category=11&difficulty=easy&type=boolean', 'general knowledge': 'https://opentdb.com/api.php?amount=50&category=9&difficulty=easy&type=boolean', 'music': 'https://opentdb.com/api.php?amount=50&category=12&difficulty=easy&type=boolean', 'science & nature': 'https://opentdb.com/api.php?amount=50&category=17&difficulty=easy&type=boolean', 'sports': 'https://opentdb.com/api.php?amount=50&category=21&difficulty=easy&type=boolean'}, 'medium': {'books': 'https://opentdb.com/api.php?amount=50&category=10&difficulty=medium&type=boolean', 'films': 'https://opentdb.com/api.php?amount=50&category=11&difficulty=medium&type=boolean', 'general knowledge': 'https://opentdb.com/api.php?amount=50&category=9&difficulty=medium&type=boolean', 'music': 'https://opentdb.com/api.php?amount=50&category=12&difficulty=medium&type=boolean', 'science & nature': 'https://opentdb.com/api.php?amount=50&category=17&difficulty=medium&type=boolean', 'sports': 'https://opentdb.com/api.php?amount=50&category=21&difficulty=medium&type=boolean'}}
easy
medium
Select a category, for easy press 1, for medium press 2: 1
You selected the easy difficulty level
The subjects can be: 
0 general knowledge
1 books
2 films
3 music
4 sports
5 science & nature
{'easy': 'science & nature', 'medium': {'general knowledge': 'https://opentdb.com/api.php?amount=50&category=9&difficulty=medium&type=boolean', 'books': 'https://opentdb.com/api.php?amount=50&category=10&difficulty=medium&type=boolean', 'films': 'https://opentdb.com/api.php?amount=50&category=11&difficulty=medium&type=boolean', 'music': 'https://opentdb.com/api.php?amount=50&category=12&difficulty=medium&type=boolean', 'sports': 'https://opentdb.com/api.php?amount=50&category=21&difficulty=medium&type=boolean', 'science & nature': 'https://opentdb.com/api.php?amount=50&category=17&difficulty=medium&type=boolean'}}

Откуда все категории для easy go? Почему вместо этого я получаю 'science & nature'?

Ответы [ 2 ]

6 голосов
/ 28 февраля 2020

Вы возвращаетесь к словарю здесь:

for i, cat[selectedcat] in enumerate(cat[selectedcat]):

Вы просите for l oop назначить i и cat[selectedcat]. Не делайте этого.

Выше по сути дела это делается:

iterator = iter(enumerate(cat[selectedcat]))
while True:
    try:
        next_item = next(iterator)
    except StopIteration:
        break
    i, cat[selectedcat] = next_item

и поэтому присваивает каждому значению от cat[selectedcat] до cat[selectedcat] самой .

Это работает, потому что исходный словарь, на который ссылается cat[selectedcat], все еще ссылается на объект enumerate(), и поэтому все его ключи все еще создаются в l oop. Но сам словарь cat просят заменить значение ключа selectedcat на каждую из строк категории по очереди. Это может произойти, потому что тогда вы печатаете новое значение для cat[selectedcat] внутри l oop.

Если вы хотите показать значения с числами, вы хотите использовать другое, новое имя переменной для l oop, например:

for i, category in enumerate(cat[selectedcat]):
    print(i, category)

Здесь category - новая переменная (как и i).

2 голосов
/ 28 февраля 2020

Проблема в этой строке:

    for i, cat[selectedcat] in enumerate(cat[selectedcat]):

Каждый раз, когда через l oop присваивается элемент от cat[selectedcat] до cat[selectedcat], который модифицирует словарь. Поэтому в первый раз через l oop он делает

cat[selectedcat] = cat[selectedcat][0]

Когда l oop завершится, значение cat[selectedcat] будет последним элементом cat[selectedcat].

Обычно вы должны использовать обычные переменные для ваших l oop переменных:

for i, value in enumerate(cat[selectedcat]):
    print(i, value)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...