字典更改无明显原因

Ton*_*ony 0 python printing dictionary

出于学习原因,我正在尝试创建一个琐事游戏,但是我的字典发生了一些我无法理解的奇怪事情。

我通常测试的代码是这样的:

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)
Run Code Online (Sandbox Code Playgroud)

因此,当最后运行代码时,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'}}
Run Code Online (Sandbox Code Playgroud)

所有类别都easy去哪儿了?为什么我最终会'science & nature'改为?

Mar*_*ers 6

您正在此处分配回字典:

for i, cat[selectedcat] in enumerate(cat[selectedcat]):
Run Code Online (Sandbox Code Playgroud)

您要求for循环分配给i cat[selectedcat]。不要那样做。

以上基本上是这样做的:

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

因此将每个值 from 分配cat[selectedcat] cat[selectedcat]它自己

它碰巧工作,因为引用的原始字典cat[selectedcat]仍然被enumerate()对象引用,所以它的所有键仍然在循环中生成。但是cat字典本身被要求selectedcat依次用每个类别字符串替换键的值。您可以看到这种情况发生,因为您随后在循环内部打印了新值cat[selectedcat]

如果您想用数字显示值,您需要为循环使用不同的新变量名,例如:

for i, category in enumerate(cat[selectedcat]):
    print(i, category)
Run Code Online (Sandbox Code Playgroud)

这里,category是一个新变量(就像i是)。