[英]Sort multiple dictionaries identically, based on a specific order defined by a list
我有一个特殊情况,必须根据列表中项目的确切顺序(不是按字母顺序排序)对多个现有字典进行排序。 例如,字典是:
dict_one = {"LastName": "Bar", "FirstName": "Foo", "Address": "Example Street 101", "Phone": "012345678"}
dict_two = {"Phone": "001122334455", "LastName": "Spammer", "FirstName": "Egg", "Address": "SSStreet 123"}
dict_three = {"Address": "Run Down Street 66", "Phone": "0987654321", "LastName": "Biker", "FirstName": "Random"}
名单是:
data_order = ["FirstName", "LastName", "Phone", "Address"]
预期的结果是能够创建这样的文件:
FirstName;LastName;Phone;Address
Foo;Bar;012345678;Example Street 101
Egg;Spammer;001122334455;SSStreet 123
Random;Biker;0987654321;Run Down Street 66
注意 :在我的情况下,实际使用的是使用pyexcel-xls的Excel文件,但上面的类似CSV的示例可能更接近通常所做的,因此答案可能更普遍适用于CSV而不是Excel。
在这种情况下,我有点困难在Stack Overflow中找到任何好的答案,但最终我得到了排序工作,我可以使用它来创建文件。 标题行可以直接从下面的data_order
列表中获取。 这是我如何做到的 - 希望它可以帮助某人:
from collections import OrderedDict
import pprint
dict_one = {
"LastName": "Bar",
"FirstName": "Foo",
"Address": "Example Street 101",
"Phone": "012345678"}
dict_two = {
"Phone": "001122334455",
"LastName": "Spammer",
"FirstName": "Egg",
"Address": "SSStreet 123"}
dict_three = {
"Address": "Run Down Street 66",
"Phone": "0987654321",
"LastName": "Biker",
"FirstName": "Random"}
dict_list = []
dict_list.append(dict_one)
dict_list.append(dict_two)
dict_list.append(dict_three)
data_order = ["FirstName", "LastName", "Phone", "Address"]
result = []
for dictionary in dict_list:
result_dict = OrderedDict()
# Go through the data_order in order
for key in data_order:
# Populate result_dict in the list order
result_dict[key] = dictionary[key]
result.append(result_dict)
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(result)
"""
[ { 'FirstName': 'Foo',
'LastName': 'Bar',
'Phone': '012345678',
'Address': 'Example Street 101'},
{ 'FirstName': 'Egg',
'LastName': 'Spammer',
'Phone': '001122334455',
'Address': 'SSStreet 123'},
{ 'FirstName': 'Random',
'LastName': 'Biker',
'Phone': '0987654321',
'Address': 'Run Down Street 66'}]
"""
这可以在一个衬里中实现,尽管它更难以阅读。 如果它对某人有用:
print [OrderedDict([(key, d[key]) for key in data_order]) for d in [dict_one, dict_two, dict_three]]
这是csv.DictWriter
的经典用例,因为您的预期输出是类似CSV的(支持半冒号分隔符而不是逗号),它可以为您处理所有这些,避免需要涉及OrderedDict
荒谬解决方法,以及制作很容易读回数据而不用担心极端情况( csv
在必要时自动引用字段,并根据需要解析引入的字段):
with open('outputfile.txt', 'w', newline='') as f:
csvout = csv.DictWriter(f, data_order, delimiter=';')
# Write the header
csvout.writeheader()
csvout.writerow(dict_one)
csvout.writerow(dict_two)
csvout.writerow(dict_three)
就是这样, csv
处理排序,(它知道从作为fieldnames
data_order
传递给DictWriter
构造函数的data_order
的正确顺序),格式化等。
如果您需要从许多dict
中按特定顺序提取值而不编写它们(因为您的用例甚至不使用键),可以使用operator.itemgetter
来显着简化:
from operator import itemgetter
getfields = itemgetter(*data_order)
dict_one_fields = getfields(dict_one)
将dict_one_fields
请求顺序中所请求字段的tuple
('Foo', 'Bar', '012345678', 'Example Street 101')
,并且运行速度明显快于在Python层重复索引( itemgetter
创建一个C级“functor”,可以在一次调用中检索所有请求的值,对于像str
这样的内置键,根本没有Python级字节代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.