根据列表定义的特定顺序,以相同方式对多个词典进行排序

时间:2016-09-14 12:17:28

标签: python python-3.x sorting

我有一个特殊情况,必须根据列表中项目的确切顺序(不是按字母顺序排序)对多个现有词典进行排序。例如,词典是:

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的示例可能更接近通常所做的,因此答案可能比Excel普遍适用于CSV。

3 个答案:

答案 0 :(得分:0)

在这种情况下,我有点困难在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'}]
"""

答案 1 :(得分:0)

这可以在一个衬里中实现,尽管它更难以阅读。如果它对某人有用:

print [OrderedDict([(key, d[key]) for key in data_order]) for d in [dict_one, dict_two, dict_three]]

答案 2 :(得分:0)

这是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处理排序,(它知道data_order作为fieldnames传递给DictWriter构造函数的正确顺序),格式化,等

如果您需要从许多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创建的str一个C级"仿函数"它可以在一次调用中检索所有请求的值,对于像>>> a=[[1.343465432, 7.423334343], [6.967997797, 4.5522577]] >>> [["%.2f" % i for i in l] for l in a] [['1.34', '7.42'], ['6.97', '4.55']] 这样的内置键没有Python级字节代码。