簡體   English   中英

根據列表定義的特定順序,以相同方式對多個詞典進行排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM