Python 字典键对

Python dictionary key pairs

提问人:JennyL 提问时间:11/7/2023 最后编辑:Goku - stands with PalestineJennyL 更新时间:11/7/2023 访问量:127

问:

我有一本字典是这样格式化的:

    enemyType = {"skeleton": [{"HP": random.randint(12,15), "DMG": random.randint(3,7)}],
        "zombie": [{"HP": random.randint(21,33), "DMG": random.randint(5,9)}],
        "golem": [{"HP": random.randint(40,55), "DMG": random.randint(6,13)}]}


    for key, value in enemyType.items():
     print(key, value)
     for k, v in value:
       print(k)
    

输出为:

    skeleton [{'HP': 14, 'DMG': 3}]
    HP
    zombie [{'HP': 28, 'DMG': 8}]
    HP
    golem [{'HP': 45, 'DMG': 8}]
    HP

如何获取“HP”和“DMG”的值?

谢谢

python-3.x 列表 字典

评论

1赞 Benjamin Ecker 11/7/2023
你为什么要这样格式化呢?

答:

2赞 S.B 11/7/2023 #1

字典的值 ->包含一个项目的列表 ->键和值:

import random

enemyType = {
    'skeleton': [{'HP': random.randint(12, 15), 'DMG': random.randint(3, 7)}],
    'zombie': [{'HP': random.randint(21, 33), 'DMG': random.randint(5, 9)}],
    'golem': [{'HP': random.randint(40, 55), 'DMG': random.randint(6, 13)}],
}

for k, v in enemyType.items():
    d = v[0]
    print(k, d['HP'], d['DMG'])

输出:

skeleton 14 3
zombie 21 9
golem 40 11

我想你可以消除列表,这样你的结构是这样的:

enemyType = {
    'skeleton': {'HP': random.randint(12, 15), 'DMG': random.randint(3, 7)},
    'zombie': {'HP': random.randint(21, 33), 'DMG': random.randint(5, 9)},
    'golem': {'HP': random.randint(40, 55), 'DMG': random.randint(6, 13)},
}
1赞 mandy8055 11/7/2023 #2

您可以通过循环访问字典,然后访问列表中嵌套字典的键来访问 和 的值。像这样:HPDMG

for k, v in enemyType.items():
    print(k, v)
    for enemy in v:
        hp = enemy['HP']
        dmg = enemy['DMG']
        print("HP:", hp, "DMG:", dmg)

输出:

skeleton [{'HP': 12, 'DMG': 3}]
HP: 12 DMG: 3
zombie [{'HP': 33, 'DMG': 7}]
HP: 33 DMG: 7
golem [{'HP': 45, 'DMG': 6}]
HP: 45 DMG: 6

代码演示

1赞 Goku - stands with Palestine 11/7/2023 #3

首先,您需要更正 for 循环中的拼写错误。

import random

enemyType = {
    'skeleton': [{'HP': random.randint(12, 15), 'DMG': random.randint(3, 7)}],
    'zombie': [{'HP': random.randint(21, 33), 'DMG': random.randint(5, 9)}],
    'golem': [{'HP': random.randint(40, 55), 'DMG': random.randint(6, 13)}],
}

[(k,v[0]['HP'],v[0]['DMG']) for k, v in enemyType.items()]

#output
[('skeleton', 15, 3), ('zombie', 28, 6), ('golem', 41, 7)]

如果你只是想,然后:'HP''DMG'

[(v[0]['HP'],v[0]['DMG']) for k, v in enemyType.items()]

#output
[(15, 3), (28, 6), (41, 7)]

如果要从字典中删除列表,只需执行以下操作:

enemyType = {k:v[0] for k,v in enemyType.items()}

#output
{'skeleton': {'HP': 15, 'DMG': 3},
 'zombie': {'HP': 28, 'DMG': 6},
 'golem': {'HP': 41, 'DMG': 7}}

for key, value in enemyType.items():
    for k,v in value.items():
        print(k,v)

HP 15
DMG 3
HP 28
DMG 6
HP 41
DMG 7
1赞 Reilas 11/7/2023 #4

"... How do I get the values for 'HP' and 'DMG'? ..."

The values are within a list, so you'll need to specify this indice first.

import random as r
d = {'skeleton': [{'HP': r.randint(12,15), 'DMG': r.randint(3,7)}],
     'zombie':   [{'HP': r.randint(21,33), 'DMG': r.randint(5,9)}],
     'golem':    [{'HP': r.randint(40,55), 'DMG': r.randint(6,13)}]}
for k, v in d.items():
    hp, dmg = v[0]['HP'], v[0]['DMG']
    print(k, hp, dmg)

Optionally, use only a dictionary.

import random as r
d = {'skeleton': {'HP': r.randint(12,15), 'DMG': r.randint(3,7)},
     'zombie':   {'HP': r.randint(21,33), 'DMG': r.randint(5,9)},
     'golem':    {'HP': r.randint(40,55), 'DMG': r.randint(6,13)}}
for k, v in d.items():
    hp, dmg = v['HP'], v['DMG']
    print(k, hp, dmg)

Output

skeleton 14 4
zombie 28 8
golem 54 11
0赞 Aaron 11/7/2023 #5

Here's what happened in your existing code: basically you accidentally formatted your data structure and your loops in a way that didn't cause an explicit error which is usually how you know something is wrong.for

for key, value in enemyDict.items():
    print(key, value) #here value is a list containing a single dict
    
    for k, v in value: #Iterating over the list yields a single iteration over this loop
        #For each loop iteration you are trying to unpack the new value into two new variables.
        #  This only works here because your dict (the first and only value in the list)
        #  also only has two keys. Treating the dict as an iterable (without calling .items
        #  or .values for example) will simply iterate over the keys
       print(k) #here k will be the first key in the dict: "HP", and v will be the second: "DMG".

If you did not mean to have the extra list it is quite simple to remove it:

enemyType = {
    "skeleton": {"HP": random.randint(12,15), "DMG": random.randint(3,7)},
    "zombie": {"HP": random.randint(21,33), "DMG": random.randint(5,9)},
    "golem": {"HP": random.randint(40,55), "DMG": random.randint(6,13)}
}

for key, value in enemyDict.items():
    print(key, value)
    for k, v in value.items(): #note the added "items" to get key and value pairs from the dict
        print(k, v)

If you did mean for the list to be there (for example if you are trying to represent multiple instances of each enemy), you can also adjust the loop accordingly:

enemyType = {
    #using list comprehensions to create multiple enemies of each type
    "skeleton": [{"HP": random.randint(12,15), "DMG": random.randint(3,7)} for _ in range(3)],
    "zombie": [{"HP": random.randint(21,33), "DMG": random.randint(5,9)} for _ in range(4)],
    "golem": [{"HP": random.randint(40,55), "DMG": random.randint(6,13)} for _ in range(2)]
}

for enemy_type, instances in enemyDict.items(): #get enemy type and list of enemy instances of that type
    print(enemy_type)
    for enemy_instance in instances: #each instance is a dict containing specific "HP" and "DMG" for each enemy
        print(enemy_instance["HP"], enemy_instance["DMG"])