Python 如何创建一个字典,为键重新生成值?

Python 如何创建一个字典,为键重新生成值?,python,function,dictionary,tuples,Python,Function,Dictionary,Tuples,我有以下宠物清单: pets = [("Fido", "John", "Malkovic", 22), ("Butch", "Jake", "Smirnoff", 18), ("Zooma", "Simon", "Ng", 32), ("Chase", "Marth

我有以下宠物清单:

pets = [("Fido", "John", "Malkovic", 22),
    ("Butch", "Jake", "Smirnoff", 18),
    ("Zooma", "Simon", "Ng", 32),
    ("Chase", "Martha", "Black", 73),
    ("Rocky", "Simon", "Ng", 32)]
我需要创建一个函数,它接受这样的列表结构,并给出一个字典,其中名称、姓氏和年龄用作键,狗的名字用作值。对于这个特定的列表,答案是

{("John", "Malkovic", 22): ["Fido"],
 ("Jake", "Smirnoff", 18): ["Butch"],
 ("Simon", "Ng", 32): ["Zooma", "Rocky"],
 ("Martha", "Black", 73): ["Chase"]
}
我试图做的是创建一个键列表,创建一个值列表,然后尝试将它们放入字典中

q=[]
for i in pets:
    q.append(tuple(i[-3:]))
此步骤为我提供了一个密钥列表:

[('John', 'Malkovic', 22), ('Jake', 'Smirnoff', 18), ('Simon', 'Ng', 32), ('Martha', 'Black', 73), ('Simon', 'Ng', 32)]
然后我创建一个值列表:

b=[]
for i in pets:
    b.append(i[0])
它给了我这个清单:

['Fido', 'Butch', 'Zooma', 'Chase', 'Rocky']
然后我尝试使用以下两个列表填充字典:

d=dict(zip(q,b))
但是我没有得到我需要的:

{('John', 'Malkovic', 22): 'Fido', ('Jake', 'Smirnoff', 18): 'Butch', ('Simon', 'Ng', 32): 'Rocky', ('Martha', 'Black', 73): 'Chase'}
首先,这种方法不允许我为一个键输入两个值(在这种情况下,我必须将值“Zooma”和“Rocky”与键(“Simon”,“Ng”,32)”配对),其次,如果包含键的列表有两个相似的键(在这种情况下,它有两个(“Simon”,“Ng”,32)”的实例),它会跳过一个值
如何创建这样一个字典?

您可以使用
defaultdict(list)
——当所有者不是字典的键时,这会自动创建一个新列表,如果它们已经是键,则会附加到该列表:

从集合导入defaultdict
d=默认DICT(列表)
对于宠物中的行:
d[行[1:][]。追加(行[0])

您可以使用
defaultdict(list)
——当所有者不是字典的键时,这会自动创建一个新列表,如果它们已经是键,则会附加到该列表:

从集合导入defaultdict
d=默认DICT(列表)
对于宠物中的行:
d[行[1:][]。追加(行[0])
如果您这样做:

d = dict(zip(q,b))
发生的情况是,将
q
b
配对,然后将每个条目视为字典的键/值对。如果
q
有重复的条目,这意味着相同的键将被设置两次,其值将被覆盖(不跳过)

您希望您的值是值列表,但上面的命令会将它们设置为直接值(请注意,您自己的示例中宠物不在列表中)

一个遵循您的逻辑直到最后一步的解决方案是使用列表的
defaultdict

from collections import defaultdict

# ...

d = defaultdict(list)
for person, pet in zip(q, b):
    d[person].append(pet)
defaultdict
避免了必须为每个值创建一个新列表,并为每个新键创建一个空列表以添加到,而只是添加到现有键的列表中

但是,更简单的方法是一次创建字典:

from collections import defaultdict

pets = [("Fido", "John", "Malkovic", 22),
    ("Butch", "Jake", "Smirnoff", 18),
    ("Zooma", "Simon", "Ng", 32),
    ("Chase", "Martha", "Black", 73),
    ("Rocky", "Simon", "Ng", 32)]


d = defaultdict(list)
for pet, first, last, age in pets:
    d[(first, last, age)].append(pet)
或者,如果您确实不想使用
defaultdict

d = {}
for pet, first, last, age in pets:
    key = (first, last, age)
    if key not in d:
        d[key] = []
    d[key].append(pet)
如果您这样做:

d = dict(zip(q,b))
发生的情况是,将
q
b
配对,然后将每个条目视为字典的键/值对。如果
q
有重复的条目,这意味着相同的键将被设置两次,其值将被覆盖(不跳过)

您希望您的值是值列表,但上面的命令会将它们设置为直接值(请注意,您自己的示例中宠物不在列表中)

一个遵循您的逻辑直到最后一步的解决方案是使用列表的
defaultdict

from collections import defaultdict

# ...

d = defaultdict(list)
for person, pet in zip(q, b):
    d[person].append(pet)
defaultdict
避免了必须为每个值创建一个新列表,并为每个新键创建一个空列表以添加到,而只是添加到现有键的列表中

但是,更简单的方法是一次创建字典:

from collections import defaultdict

pets = [("Fido", "John", "Malkovic", 22),
    ("Butch", "Jake", "Smirnoff", 18),
    ("Zooma", "Simon", "Ng", 32),
    ("Chase", "Martha", "Black", 73),
    ("Rocky", "Simon", "Ng", 32)]


d = defaultdict(list)
for pet, first, last, age in pets:
    d[(first, last, age)].append(pet)
或者,如果您确实不想使用
defaultdict

d = {}
for pet, first, last, age in pets:
    key = (first, last, age)
    if key not in d:
        d[key] = []
    d[key].append(pet)
输出:

{('John', 'Malkovic', 22): ['Fido'], ('Jake', 'Smirnoff', 18): ['Butch'], ('Simon', 'Ng', 32): ['Zooma', 'Rocky'], ('Martha', 'Black', 73): ['Chase']}
输出:

{('John', 'Malkovic', 22): ['Fido'], ('Jake', 'Smirnoff', 18): ['Butch'], ('Simon', 'Ng', 32): ['Zooma', 'Rocky'], ('Martha', 'Black', 73): ['Chase']}

非常感谢。谢谢你!这有帮助