首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用了Python中的pprint.pprint之后,我能避免排序字典输出吗?

在使用了Python中的pprint.pprint之后,我能避免排序字典输出吗?
EN

Stack Overflow用户
提问于 2018-08-10 14:11:27
回答 5查看 3.1K关注 0票数 14

守则是:

代码语言:javascript
运行
复制
from pprint import pprint
d = {"b" : "Maria", "c" : "Helen", "a" : "George"}
pprint(d, width = 1)

产出如下:

代码语言:javascript
运行
复制
{'a': 'George',
'b': 'Maria',
'c': 'Helen'}

但是,期望的输出是:

代码语言:javascript
运行
复制
{'b': 'Maria',
'c': 'Helen',
'a': 'George'}

这可以用pprint来完成吗?还是有其他的方法?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-08-10 14:50:41

Python 3.8或更高版本:

您可以使用sort_dicts=False防止按字母顺序对它们进行排序:

代码语言:javascript
运行
复制
pprint.pprint(data, sort_dicts=False)

Python 3.7或更高版本:

由于Python3.7(或者cPython为3.6 ),dict保留了插入顺序。对于之前的任何版本,您都需要使用OrderedDict来保持密钥的有序性。

虽然,来自pprint

在计算显示之前,字典将按键排序。

这意味着pprint将打破您想要的订单。

替代方法:

您还可以使用json.dumps漂亮地打印数据。

代码:

代码语言:javascript
运行
复制
import json
from collections import OrderedDict

# For Python 3.6 and prior, use an OrderedDict
d = OrderedDict(b="Maria", c="Helen", a="George")

print(json.dumps(d, indent=1))

输出:

代码语言:javascript
运行
复制
{
 "b": "Maria",
 "c": "Helen",
 "a": "George"
}
票数 19
EN

Stack Overflow用户

发布于 2018-08-10 14:43:38

如果您阅读pprint.py的源代码,您会发现在PrettyPrinter._pprint_dict()中,负责格式化dicts的方法:

代码语言:javascript
运行
复制
def _pprint_dict(self, object, stream, indent, allowance, context, level):
    write = stream.write
    write('{')
    if self._indent_per_level > 1:
        write((self._indent_per_level - 1) * ' ')
    length = len(object)
    if length:
        items = sorted(object.items(), key=_safe_tuple)
        self._format_dict_items(items, stream, indent, allowance + 1,
                                context, level)
    write('}')

_dispatch[dict.__repr__] = _pprint_dict

这里有一行items = sorted(object.items(), key=_safe_tuple),所以在处理格式化之前,dict项总是先排序,您必须自己重写它,方法是复制和粘贴它,并在您自己的脚本中删除违规行:

代码语言:javascript
运行
复制
import pprint as pp
def _pprint_dict(self, object, stream, indent, allowance, context, level):
    write = stream.write
    write('{')
    if self._indent_per_level > 1:
        write((self._indent_per_level - 1) * ' ')
    length = len(object)
    if length:
        self._format_dict_items(object.items(), stream, indent, allowance + 1,
                                context, level)
    write('}')
pp.PrettyPrinter._dispatch[dict.__repr__] = _pprint_dict

因此:

代码语言:javascript
运行
复制
pp.pprint({"b" : "Maria", "c" : "Helen", "a" : "George"}, width=1)

将输出(在Python中):

代码语言:javascript
运行
复制
{'b': 'Maria',
 'c': 'Helen',
 'a': 'George'}
票数 4
EN

Stack Overflow用户

发布于 2019-04-13 00:58:10

一个更通用的解决方案是使用unittest.mock.patch覆盖内置的sorted函数,该函数只返回给定的第一个参数:

代码语言:javascript
运行
复制
import pprint
from unittest.mock import patch

def unsorted_pprint(*args, **kwargs):
    with patch('builtins.sorted', new=lambda l, **_: l):
        orig_pprint(*args, **kwargs)

orig_pprint = pprint.pprint
pprint.pprint = unsorted_pprint

因此:

代码语言:javascript
运行
复制
pprint.pprint({"b" : "Maria", "c" : "Helen", "a" : "George"})

产出:

代码语言:javascript
运行
复制
{'b': 'Maria', 'c': 'Helen', 'a': 'George'}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51788397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档