嵌套字典中的多个键
multiple keys in nested dictionary
代码:
from operator import itemgetter
names = {
'Bucky': 'Roberts',
'Tom': 'Roberts',
'Bernie' : 'Zunks',
'Jenna' : 'Hayes',
'Sally': 'Jones',
'Amanda':'Roberts',
'Tom':'Williams',
'Dean':'Hayes',
'Bernie':'Barbie',
'Tom':'Jones'
}
users = []
for k,v in names.items():
users.append({'fname':k,'lname':v})
print(users)
for x in sorted(users, key=itemgetter('fname')):
print(x)
问题:对于最后一个 for
循环(排序)显示字典 names
的所有条目,我需要所有条目,即重复键(一对多映射)也。但是在创建嵌套字典 users
时遗漏了 2 Tom(s)
和 1 Bernie
。如何避免使用python 3.4?
一些可能的改进,但对于您的主要问题,使用全名和 set
作为您的结构,并在 space 上使用 split
创建另一个字典(我不确定你是否需要):
names = {
'Bucky Roberts',
'Tom Roberts',
'Bernie Zunks',
'Jenna Hayes',
'Sally Jones',
'Amanda Roberts',
'Tom Williams',
'Dean Hayes',
'Bernie Barbie',
'Tom Jones'
}
users = []
for name in names:
k, v = name.split()
users.append({'fname':k,'lname':v})
for x in sorted(users, key=itemgetter('fname')):
print(x)
生产:
{'fname': 'Amanda', 'lname': 'Roberts'}
{'fname': 'Bernie', 'lname': 'Barbie'}
{'fname': 'Bernie', 'lname': 'Zunks'}
{'fname': 'Bucky', 'lname': 'Roberts'}
{'fname': 'Dean', 'lname': 'Hayes'}
{'fname': 'Jenna', 'lname': 'Hayes'}
{'fname': 'Sally', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Williams'}
{'fname': 'Tom', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Roberts'}
编辑:使用元组并添加 Betty Sue Johnson
:
names = {
('Bucky', 'Roberts'),
('Betty Sue', 'Johnson'),
('Tom', 'Roberts'),
('Bernie', 'Zunks'),
('Jenna', 'Hayes'),
('Sally', 'Jones'),
('Amanda', 'Roberts'),
('Tom', 'Williams'),
('Dean', 'Hayes'),
('Bernie', 'Barbie'),
('Tom', 'Jones')
}
for each in sorted([{'fname':n[0], 'lname':n[1]} for n in names], key=itemgetter('fname')):
print(each)
输出:
{'fname': 'Amanda', 'lname': 'Roberts'}
{'fname': 'Bernie', 'lname': 'Zunks'}
{'fname': 'Bernie', 'lname': 'Barbie'}
{'fname': 'Betty Sue', 'lname': 'Johnson'}
{'fname': 'Bucky', 'lname': 'Roberts'}
{'fname': 'Dean', 'lname': 'Hayes'}
{'fname': 'Jenna', 'lname': 'Hayes'}
{'fname': 'Sally', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Roberts'}
{'fname': 'Tom', 'lname': 'Williams'}
{'fname': 'Tom', 'lname': 'Jones'}
您也可以使用 defaultdict
考虑以下
from collections import defaultdict
names = defaultdict(list)
names['Bucky'].append('Roberts')
names['Tom'].append('Roberts')
names['Bernie'].append('Zunks')
names['Jenna'].append('Hayes')
names['Sally'].append('Jones')
names['Amanda'].append('Roberts')
names['Tom'].append('Williams')
names['Dean'].append('Hayes')
names['Bernie'].append('Barbie')
names['Tom'].append('Jones')
print names
输出:
defaultdict(list,
{'Amanda': ['Roberts'],
'Bernie': ['Zunks', 'Barbie'],
'Bucky': ['Roberts'],
'Dean': ['Hayes'],
'Jenna': ['Hayes'],
'Sally': ['Jones'],
'Tom': ['Roberts', 'Williams', 'Jones']})
解释
names = defaultdict(list)
初始化一个创建空列表的字典,而不是在查询不存在的键时抛出 KeyError
。
因此,您可以像在字典中一样附加到新键。
制作用户列表可以如下
users = []
for fname in names:
for lname in names[fname]:
users.append({'fname': fname, 'lname': lname})
A dict
不能有重复键,您可能需要考虑另一种数据结构,例如元组列表。
from operator import itemgetter
names = [
('Bucky', 'Roberts'),
('Tom', 'Roberts'),
('Bernie', 'Zunks'),
('Jenna', 'Hayes'),
('Sally', 'Jones'),
('Amanda','Roberts'),
('Tom', 'Williams'),
('Dean', 'Hayes'),
('Bernie', 'Barbie'),
('Tom', 'Jones')
]
users = [{'fname': k,'lname': v} for k, v in names]
@Rex5,字典定义为具有唯一键的项目的无序集合。
Keys should be immutable data items but values can be mutable/immutable both.
因此,定义本身在创建 names 字典时过滤掉重复的值,因此没有机会在 for 循环中包含重复的副本。
看看下面的示例。在此之后我还修改了您的代码示例。
Focus on keys Sam and Kim.
import json
# Creating list of users (Dictionary) with duplicated keys
users = {
"Sam": "Smith",
"Samuel": "Badri",
"Kim": "Jones",
"Jim": "Hollowen",
"Sam": "Paul",
"Joel": "Brown",
"Kim": "Fillo",
"Sam": "Koelli",
"Tinnu": "Timmon"
}
# Pretty printing the dictionary
# Keys, Sam & Kim will appear only once even after their multiple occurrences
print( json.dumps(users, indent=4))
# {
# "Kim": "Fillo",
# "Sam": "Koelli",
# "Tinnu": "Timmon",
# "Jim": "Hollowen",
# "Joel": "Brown",
# "Samuel": "Badri"
# }
I have also tried to provide an alternative answer that fulfills the need as follows (What I did is I just modified the dictionary and for loop).
from operator import itemgetter
names = {
'Bucky': 'Roberts',
'Tom': ['Roberts', 'Williams', 'Jones'],
'Bernie' : ['Zunks', 'Barbie'],
'Jenna' : 'Hayes',
'Sally': 'Jones',
'Amanda':'Roberts',
'Dean':'Hayes',
}
users = []
for k,v in names.items():
if type(v) == type([]):
for lname in v:
users.append({'fname': k, 'lname': lname})
else:
users.append({'fname':k, 'lname':v})
print(users)
"""
[{'lame': 'Zunks', 'fname': 'Bernie'}, {'lname': 'Barbie',
'fname': 'Bernie'}, {'lname': 'Jones', 'fname': 'Sally'},
{'lname': 'Hayes', 'fname': 'Jenna'}, {'lname': 'Roberts',
'fname': 'Amanda'}, {'lname': 'Roberts', 'fname': 'Bucky'},
{'lname': 'Hayes', 'fname': 'Dean'}, {'lname': 'Roberts',
'fname': 'Tom'}, {'lname': 'Williams', 'fname': 'Tom'},
{'lname': 'Jones', 'fname': 'Tom'}]
"""
for x in sorted(users, key=itemgetter('fname')):
print(x)
"""
{'lname': 'Roberts', 'fname': 'Amanda'}
{'lname': 'Zunks', 'fname': 'Bernie'}
{'lname': 'Barbie', 'fname': 'Bernie'}
{'lname': 'Roberts', 'fname': 'Bucky'}
{'lname': 'Hayes', 'fname': 'Dean'}
{'lname': 'Hayes', 'fname': 'Jenna'}
{'lname': 'Jones', 'fname': 'Sally'}
{'lname': 'Roberts', 'fname': 'Tom'}
{'lname': 'Williams', 'fname': 'Tom'}
{'lname': 'Jones', 'fname': 'Tom'}
"""
字典不能有重复的键,因此原始数据需要更改为其他内容...例如全名字符串列表,其中包含以空格分隔的名字和姓氏。
在 Python 3.6 之前,字典中的项目是无序的,因此您可以将结果存储在 collections.OrderedDict
子类中,以保留插入键的顺序(如果您希望这样做的话)保留(将在 Python 3.6 和更早版本中继续工作)。
把所有东西放在一起,会产生这样的结果:
from collections import OrderedDict
from operator import itemgetter
from pprint import pprint
names = ['Bucky Roberts',
'Tom Roberts',
'Bernie Zunks',
'Jenna Hayes',
'Amanda Roberts',
'Tom Williams',
'Dean Hayes',
'Bernie Barbie',
'Tom Jones',]
users = OrderedDict()
for name in sorted(names):
fname, lname = name.split()
users.setdefault(fname, []).append(lname)
pprint(users)
输出:
OrderedDict([('Amanda', ['Roberts']),
('Bernie', ['Zunks', 'Barbie']),
('Bucky', ['Roberts']),
('Dean', ['Hayes']),
('Jenna', ['Hayes']),
('Tom', ['Roberts', 'Williams', 'Jones'])])
代码:
from operator import itemgetter
names = {
'Bucky': 'Roberts',
'Tom': 'Roberts',
'Bernie' : 'Zunks',
'Jenna' : 'Hayes',
'Sally': 'Jones',
'Amanda':'Roberts',
'Tom':'Williams',
'Dean':'Hayes',
'Bernie':'Barbie',
'Tom':'Jones'
}
users = []
for k,v in names.items():
users.append({'fname':k,'lname':v})
print(users)
for x in sorted(users, key=itemgetter('fname')):
print(x)
问题:对于最后一个 for
循环(排序)显示字典 names
的所有条目,我需要所有条目,即重复键(一对多映射)也。但是在创建嵌套字典 users
时遗漏了 2 Tom(s)
和 1 Bernie
。如何避免使用python 3.4?
一些可能的改进,但对于您的主要问题,使用全名和 set
作为您的结构,并在 space 上使用 split
创建另一个字典(我不确定你是否需要):
names = {
'Bucky Roberts',
'Tom Roberts',
'Bernie Zunks',
'Jenna Hayes',
'Sally Jones',
'Amanda Roberts',
'Tom Williams',
'Dean Hayes',
'Bernie Barbie',
'Tom Jones'
}
users = []
for name in names:
k, v = name.split()
users.append({'fname':k,'lname':v})
for x in sorted(users, key=itemgetter('fname')):
print(x)
生产:
{'fname': 'Amanda', 'lname': 'Roberts'}
{'fname': 'Bernie', 'lname': 'Barbie'}
{'fname': 'Bernie', 'lname': 'Zunks'}
{'fname': 'Bucky', 'lname': 'Roberts'}
{'fname': 'Dean', 'lname': 'Hayes'}
{'fname': 'Jenna', 'lname': 'Hayes'}
{'fname': 'Sally', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Williams'}
{'fname': 'Tom', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Roberts'}
编辑:使用元组并添加 Betty Sue Johnson
:
names = {
('Bucky', 'Roberts'),
('Betty Sue', 'Johnson'),
('Tom', 'Roberts'),
('Bernie', 'Zunks'),
('Jenna', 'Hayes'),
('Sally', 'Jones'),
('Amanda', 'Roberts'),
('Tom', 'Williams'),
('Dean', 'Hayes'),
('Bernie', 'Barbie'),
('Tom', 'Jones')
}
for each in sorted([{'fname':n[0], 'lname':n[1]} for n in names], key=itemgetter('fname')):
print(each)
输出:
{'fname': 'Amanda', 'lname': 'Roberts'}
{'fname': 'Bernie', 'lname': 'Zunks'}
{'fname': 'Bernie', 'lname': 'Barbie'}
{'fname': 'Betty Sue', 'lname': 'Johnson'}
{'fname': 'Bucky', 'lname': 'Roberts'}
{'fname': 'Dean', 'lname': 'Hayes'}
{'fname': 'Jenna', 'lname': 'Hayes'}
{'fname': 'Sally', 'lname': 'Jones'}
{'fname': 'Tom', 'lname': 'Roberts'}
{'fname': 'Tom', 'lname': 'Williams'}
{'fname': 'Tom', 'lname': 'Jones'}
您也可以使用 defaultdict
考虑以下
from collections import defaultdict
names = defaultdict(list)
names['Bucky'].append('Roberts')
names['Tom'].append('Roberts')
names['Bernie'].append('Zunks')
names['Jenna'].append('Hayes')
names['Sally'].append('Jones')
names['Amanda'].append('Roberts')
names['Tom'].append('Williams')
names['Dean'].append('Hayes')
names['Bernie'].append('Barbie')
names['Tom'].append('Jones')
print names
输出:
defaultdict(list,
{'Amanda': ['Roberts'],
'Bernie': ['Zunks', 'Barbie'],
'Bucky': ['Roberts'],
'Dean': ['Hayes'],
'Jenna': ['Hayes'],
'Sally': ['Jones'],
'Tom': ['Roberts', 'Williams', 'Jones']})
解释
names = defaultdict(list)
初始化一个创建空列表的字典,而不是在查询不存在的键时抛出 KeyError
。
因此,您可以像在字典中一样附加到新键。
制作用户列表可以如下
users = []
for fname in names:
for lname in names[fname]:
users.append({'fname': fname, 'lname': lname})
A dict
不能有重复键,您可能需要考虑另一种数据结构,例如元组列表。
from operator import itemgetter
names = [
('Bucky', 'Roberts'),
('Tom', 'Roberts'),
('Bernie', 'Zunks'),
('Jenna', 'Hayes'),
('Sally', 'Jones'),
('Amanda','Roberts'),
('Tom', 'Williams'),
('Dean', 'Hayes'),
('Bernie', 'Barbie'),
('Tom', 'Jones')
]
users = [{'fname': k,'lname': v} for k, v in names]
@Rex5,字典定义为具有唯一键的项目的无序集合。
Keys should be immutable data items but values can be mutable/immutable both.
因此,定义本身在创建 names 字典时过滤掉重复的值,因此没有机会在 for 循环中包含重复的副本。
看看下面的示例。在此之后我还修改了您的代码示例。
Focus on keys Sam and Kim.
import json
# Creating list of users (Dictionary) with duplicated keys
users = {
"Sam": "Smith",
"Samuel": "Badri",
"Kim": "Jones",
"Jim": "Hollowen",
"Sam": "Paul",
"Joel": "Brown",
"Kim": "Fillo",
"Sam": "Koelli",
"Tinnu": "Timmon"
}
# Pretty printing the dictionary
# Keys, Sam & Kim will appear only once even after their multiple occurrences
print( json.dumps(users, indent=4))
# {
# "Kim": "Fillo",
# "Sam": "Koelli",
# "Tinnu": "Timmon",
# "Jim": "Hollowen",
# "Joel": "Brown",
# "Samuel": "Badri"
# }
I have also tried to provide an alternative answer that fulfills the need as follows (What I did is I just modified the dictionary and for loop).
from operator import itemgetter
names = {
'Bucky': 'Roberts',
'Tom': ['Roberts', 'Williams', 'Jones'],
'Bernie' : ['Zunks', 'Barbie'],
'Jenna' : 'Hayes',
'Sally': 'Jones',
'Amanda':'Roberts',
'Dean':'Hayes',
}
users = []
for k,v in names.items():
if type(v) == type([]):
for lname in v:
users.append({'fname': k, 'lname': lname})
else:
users.append({'fname':k, 'lname':v})
print(users)
"""
[{'lame': 'Zunks', 'fname': 'Bernie'}, {'lname': 'Barbie',
'fname': 'Bernie'}, {'lname': 'Jones', 'fname': 'Sally'},
{'lname': 'Hayes', 'fname': 'Jenna'}, {'lname': 'Roberts',
'fname': 'Amanda'}, {'lname': 'Roberts', 'fname': 'Bucky'},
{'lname': 'Hayes', 'fname': 'Dean'}, {'lname': 'Roberts',
'fname': 'Tom'}, {'lname': 'Williams', 'fname': 'Tom'},
{'lname': 'Jones', 'fname': 'Tom'}]
"""
for x in sorted(users, key=itemgetter('fname')):
print(x)
"""
{'lname': 'Roberts', 'fname': 'Amanda'}
{'lname': 'Zunks', 'fname': 'Bernie'}
{'lname': 'Barbie', 'fname': 'Bernie'}
{'lname': 'Roberts', 'fname': 'Bucky'}
{'lname': 'Hayes', 'fname': 'Dean'}
{'lname': 'Hayes', 'fname': 'Jenna'}
{'lname': 'Jones', 'fname': 'Sally'}
{'lname': 'Roberts', 'fname': 'Tom'}
{'lname': 'Williams', 'fname': 'Tom'}
{'lname': 'Jones', 'fname': 'Tom'}
"""
字典不能有重复的键,因此原始数据需要更改为其他内容...例如全名字符串列表,其中包含以空格分隔的名字和姓氏。
在 Python 3.6 之前,字典中的项目是无序的,因此您可以将结果存储在 collections.OrderedDict
子类中,以保留插入键的顺序(如果您希望这样做的话)保留(将在 Python 3.6 和更早版本中继续工作)。
把所有东西放在一起,会产生这样的结果:
from collections import OrderedDict
from operator import itemgetter
from pprint import pprint
names = ['Bucky Roberts',
'Tom Roberts',
'Bernie Zunks',
'Jenna Hayes',
'Amanda Roberts',
'Tom Williams',
'Dean Hayes',
'Bernie Barbie',
'Tom Jones',]
users = OrderedDict()
for name in sorted(names):
fname, lname = name.split()
users.setdefault(fname, []).append(lname)
pprint(users)
输出:
OrderedDict([('Amanda', ['Roberts']),
('Bernie', ['Zunks', 'Barbie']),
('Bucky', ['Roberts']),
('Dean', ['Hayes']),
('Jenna', ['Hayes']),
('Tom', ['Roberts', 'Williams', 'Jones'])])