简体   繁体   English

如何避免字典项随机排序键?

[英]How to avoid dictionary items ordering keys randomly?

I've written a function to take excel columns and put them into a dictionary for outputting into json. 我已经编写了一个函数来获取excel列并将其放入字典中以输出到json中。 When I write the json output the key values appear to be randomly ordered. 当我写json输出时,键值似乎是随机排序的。 Is there a way I can enforce the key values to be in the order that I add them? 有没有一种方法可以强制将键值按添加顺序排序?

def excel_to_json(filename):
    wb = xlrd.open_workbook(filename)
    sh = wb.sheet_by_index(0)

    # List to hold dictionaries
    c_list = []

    # Iterate through each row in worksheet and fetch values into dict
    for rownum in range(1, sh.nrows):
        cars = OrderedDict()
        row_values = sh.row_values(rownum)
        cars['Name'] = row_values[0]
        cars['Extensions'] = row_values[1]
        cars['Patterns'] = row_values[2]
        cars['RansomNoteFilenames'] = row_values[3]
        cars['Comment'] = row_values[4]
        cars['EncryptionAlgorithm'] = row_values[5]
        cars['AlternateNames'] = row_values[6]
        cars['Decryptor'] = row_values[7]
        cars['AdditionalInfo1'] = row_values[8]
        cars['AdditionalInfo2'] = row_values[9]
        cars['Screenshots'] = row_values[10]

        c_list.append(cars)

    # Serialize the list of dicts to JSON
    return formatJson(json.dumps(c_list))


def formatJson(input):
    return json.dumps(json.loads(input), indent=4)

An example json output looks like the following: JSON输出示例如下所示:

 {
        "Name": "dummydata",
        "Comment": "",
        "AlternateNames": "",
        "Screenshots": "dummydata",
        "RansomNoteFilenames": "dummydata",
        "Decryptor": "",
        "Extensions": "dummydata",
        "AdditionalInfo2": "",
        "Patterns": "",
        "EncryptionAlgorithm": "dummydata",
        "AdditionalInfo1": "dummydata",
    },

As you can see the keys here are in a different order to the for loop within excel_to_json() which makes readability of the json difficult if processed manually. 如您所见,此处的键与excel_to_json()的for循环的顺序不同,这使得如果手动处理json的可读性很困难。

Do this 做这个

def formatJson(inp):
    return json.dumps(inp, indent=4)

And call it like 并称它为

formatJson(c_list)

You are dumping and loading it again an extra time. 您正在转储并将其再次加载额外的时间。

Also a slight improvement to your code 对您的代码也有一点改进

for rownum in range(1, sh.nrows):
        cars = OrderedDict()
        row_values = sh.row_values(rownum)
        row_names = ['Name','Extensions','Patterns','Comment',....]
        for i in range(len(row_values)):
            cars[row_names[i]] = row_values[i]

        c_list.append(cars)

This depends on whether the json serializer you use actually honors the order within the OrderedDict . 这取决于您使用的json序列化程序是否实际上OrderedDict的顺序。 You could try a different one (eg simplejson ) and see if it works. 您可以尝试其他方法(例如simplejson ),看看是否simplejson They are all API compatible. 它们都是API兼容的。

Also, most json.dumps implementations have a sort_keys parameter which will sort all keys alphabetically. 而且,大多数json.dumps实现都有一个sort_keys参数,该参数将按字母顺序对所有键进行排序。 This is useful when you want to have a stable representation of your data, for eg diffing, etc. 当您想要对数据进行稳定表示时(例如,差异等),此功能很有用。

ps ps

Also, your code can be made much more simple if you use the zip builtin. 另外,如果您使用内置的zip ,则可以使代码更简单。

columns = ['Name', 'Extension', 'Patterns']
row = ['Foo', 'Bar', 'Baz']
OrderedDict(zip(columns, row))

gives

OrderedDict([('Name', 'Foo'), ('Extension', 'Bar'), ('Patterns', 'Baz')])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM