如何在JSON中对对象内的对象进行排序? (使用Python 2.7)

时间:2014-03-29 06:19:55

标签: python json encoding utf-8

我有以下代码,这是一个将交易历史从数字货币钱包导出到json文件的功能。

我面临的问题有两个:

  1. 我想允许json文件以utf-8编写,作为属性'标签'可以是utf-8字符,如果我不考虑它,它将在文件中显示为\ u \ u \ u等。但是,无论编码/解码的组合和顺序如何(' utf -8'),我无法将最终输出文件打印到utf-8。

  2. 我想按照我在代码中编写的顺序对每次迭代进行排序。我从集合中尝试了OrderedDict,但它没有订购这些项目以便Date首先出现,等等。

  3. 任何帮助,弄清楚如何使用utf-8将其打印到我的文件中,并在我编写的每个项目中输入订单。

    非常感谢。

    # This line is the last line of a for loop iterating through
    # the list of transactions, "for each item in list"
    wallet_history.append({"Date": time_string, "TXHash": tx_hash, "Label": label, "Confirmations":
                          confirmations, "Amount": value_string, "Fee": fee_string, "Balance": balance_string})
    try:
        history_str = json.dumps(
            wallet_history, ensure_ascii=False, sort_keys=False, indent=4)
    except TypeError:
        QMessageBox.critical(
            None, _("Unable to create json"), _("Unable to create json"))
        jsonfile.close()
        os.remove(fileName)
        return
    jsonfile.write(history_str)
    

2 个答案:

答案 0 :(得分:2)

您需要确保两个json都不转义字符,并将json输出写为unicode:

import codecs
import json

with codecs.open('tmp.json', 'w', encoding='utf-8') as f:
    f.write(json.dumps({u'hello' : u'привет!'}, ensure_ascii=False) + '\n')


$ cat tmp.json
{"hello": "привет!"}

关于您的第二个问题:您可以使用collections.OrderedDict,但是您需要小心将其直接传递给json.dumps,而不将其更改为简单的字典。看到差异:

from collections import OrderedDict
data = OrderedDict(zip(('first', 'second', 'last'), (1, 10, 3)))
print json.dumps(dict(data)) # {"second": 10, "last": 3, "first": 1}
print json.dumps(data) # {"first": 1, "second": 10, "last": 3}

答案 1 :(得分:0)

要以UTF-8编码生成的JSON,请使用ensure_ascii=False

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
>>> import json
>>> json.dumps(u'привет!', ensure_ascii=False)
u'"\u043f\u0440\u0438\u0432\u0435\u0442!"'
>>> print json.dumps(u'привет!', ensure_ascii=False)
"привет!"
>>> with open('test', 'w') as f:
...     f.write(json.dumps(u'привет!', ensure_ascii=False))
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-6: ordinal not in range(128)
>>> with open('test', 'w') as f:
...     f.write(json.dumps(u'привет!'.encode('utf-8'), ensure_ascii=False))
... 
>>> with open('test') as f:
...     f.read()
... 
'"\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!"'
>>> print '"\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!"'
"привет!"
>>>

关于订单的第二个问题。这是不可能的(除了编写自己的序列化程序)或它没有意义:Items in JSON object are out of order using "json.dumps"?

当您将wallet_history传递给json.dumps时,它已经丢失了订单,因为它包含无序的词典。