如何用两个单子编词典

2024-05-23 13:45:31 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我有这个代码,我正在尝试创建一个从姓氏到名字的字典。我已经用我原来的字典创建了两个列表:

person_to_friends = {
    'Jay Pritchett': ['Claire Dunphy', 'Gloria Pritchett', 'Manny Delgado'], 
    'Claire Dunphy': ['Jay Pritchett', 'Mitchell Pritchett', 'Phil Dunphy'], 
    'Manny Delgado': ['Gloria Pritchett', 'Jay Pritchett', 'Luke Dunphy'], 
    'Mitchell Pritchett': ['Cameron Tucker', 'Claire Dunphy', 'Luke Dunphy'], 
    'Alex Dunphy': ['Luke Dunphy'],
    'Cameron Tucker': ['Gloria Pritchett', 'Mitchell Pritchett'], 
    'Haley Gwendolyn Dunphy': ['Dylan D-Money', 'Gilbert D-Cat'],
    'Phil Dunphy': ['Claire Dunphy', 'Luke Dunphy'],
    'Dylan D-Money': ['Chairman D-Cat', 'Haley Gwendolyn Dunphy'], 
    'Gloria Pritchett': ['Cameron Tucker', 'Jay Pritchett', 'Manny Delgado'], 
    'Luke Dunphy': ['Alex Dunphy', 'Manny Delgado', 'Mitchell Pritchett', 'Phil Dunphy']
}

family_dictionary = []
friends_dictionary = []
last_names = []
for person in person_to_friends:
    family_dictionary.append(person)
    for name in person_to_friends[person]:
        friends_dictionary.append(name)

上面的代码给了我两个列表,我试图用它们来创建一个lastnames到firstnames字典,其中键是人的lastnames,值应该是拥有这个lastname的所有人的名字。我不知道如何从这里开始。你知道吗


Tags: todictionary字典personlukefriendsphiljay
3条回答

你不需要创建两个单独的列表来解决你的问题。你可以用原稿来做这个。以下是您需要做的,按以下顺序:

  1. 从字典中提取所有名字
  2. 删除重复项
  3. 迭代每个名字,分为名字和姓氏,并填充字典

from itertools import chain

n = {}    
for v in set(chain.from_iterable([k ] + v for k, v in person_to_friends.items())):
     f, l = v.rsplit(None, 1)
     n.setdefault(l, []).append(f)
print(n)

{
    "Delgado": [
        "Manny"
    ],
    "D-Cat": [
        "Chairman",
        "Gilbert"
    ],
    "Dunphy": [
        "Claire",
        "Alex",
        "Haley Gwendolyn",
        "Phil",
        "Luke"
    ],
    "D-Money": [
        "Dylan"
    ],
    "Tucker": [
        "Cameron"
    ],
    "Pritchett": [
        "Gloria",
        "Mitchell",
        "Jay"
    ]
}

这里,person_to_friends是您的输入。也可以使用collections.defaultdict对象,而不是带有setdefaultdict。我用itertools.chain压平你的字典。使剩下的过程更简单。你知道吗


如前所述,这就是如何使用defaultdict来获得优势。你知道吗

from collections import defaultdict

n = defaultdict(list)
for v in set(chain.from_iterable([k ] + v for k, v in person_to_friends.items())):
     f, l = v.rsplit(None, 1)
     n[l].append(f)

这恰好比dict+setdefault更有效。你知道吗

你可以试试这个

from collections import defaultdict
import itertools
d = defaultdict(list)
person_to_friends = {'Jay Pritchett': ['Claire Dunphy', 'Gloria Pritchett', 'Manny Delgado'], 
'Claire Dunphy': ['Jay Pritchett', 'Mitchell Pritchett', 'Phil Dunphy'], 
'Manny Delgado': ['Gloria Pritchett', 'Jay Pritchett', 'Luke Dunphy'], 
'Mitchell Pritchett': ['Cameron Tucker', 'Claire Dunphy', 'Luke Dunphy'], 
'Alex Dunphy': ['Luke Dunphy'],
'Cameron Tucker': ['Gloria Pritchett', 'Mitchell Pritchett'], 
'Haley Gwendolyn Dunphy': ['Dylan D-Money', 'Gilbert D-Cat'],
'Phil Dunphy': ['Claire Dunphy', 'Luke Dunphy'],
'Dylan D-Money': ['Chairman D-Cat', 'Haley Gwendolyn Dunphy'], 
'Gloria Pritchett': ['Cameron Tucker', 'Jay Pritchett', 'Manny Delgado'], 
'Luke Dunphy': ['Alex Dunphy', 'Manny Delgado', 'Mitchell Pritchett', 'Phil Dunphy']
}
new_people = list(itertools.chain.from_iterable([[i.split() for i in [a]+b] for a, b in person_to_friends.items()]))
for i in new_people:
   d[i[-1]].append(i[0])

final_list = {a:list(set(b)) for a, b in d.items()}

输出:

{'Dunphy': ['Alex', 'Luke', 'Claire', 'Phil', 'Haley'], 'D-Money': ['Dylan'], 'Tucker': ['Cameron'], 'D-Cat': ['Gilbert', 'Chairman'], 'Delgado': ['Manny'], 'Pritchett': ['Mitchell', 'Gloria', 'Jay']}

不导入任何内容:

d = {}
new_people = [[i.split() for i in [a]+b] for a, b in person_to_friends.items()]
for listing in new_people:
    for i in listing:
        if i[-1] in d:
           d[i[-1]].append(i[0])
        else:
           d[i[-1]] = [i[0]]

d = {a:list(set(b)) for a, b in d.items()}

输出:

{'Dunphy': ['Alex', 'Luke', 'Claire', 'Phil', 'Haley'], 'D-Money': ['Dylan'], 'Tucker': ['Cameron'], 'D-Cat': ['Gilbert', 'Chairman'], 'Delgado': ['Manny'], 'Pritchett': ['Mitchell', 'Gloria', 'Jay']}

如果字符串的格式为<FirstName> <LastName><FirstName> <Middle> <LastName>,并且仅用空格分隔,则应该检查split function.

相关问题 更多 >