为什么 PyScripter 控制台的输出不同?
Why is the output different in PyScripter console?
来自 PyScripter (3.6.4.0) REPL 控制台:
*** Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32. ***
*** Remote Python engine is active ***
>>> d = {}
>>> d['B'] = 12
>>> d['A'] = 10
>>> d['C'] = 34
>>> d
{'A': 10, 'B': 12, 'C': 34}
这个结果让我们相信 Python 对键进行排序并且不保留插入顺序,而从版本 3.6 开始就保证了。
现在让我们在 PyScripter 之外的控制台中 运行 完全相同的 Python 版本:
Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {}
>>> d['B'] = 12
>>> d['A'] = 10
>>> d['C'] = 34
>>> d
{'B': 12, 'A': 10, 'C': 34}
插入顺序全部保留。
为什么输出不同?
在 pyscripter REPL 中,当我不依赖 REPL 提供答案而是使用 print
语句时,我得到了正确的结果:
>>> print(d)
{'B': 12, 'A': 10, 'C': 34}
其中 d
生成的键就好像它们已排序一样:
>>> d
{'A': 10, 'B': 12, 'C': 34}
所以当涉及到字典顺序时,不要相信 pyscripter REPL 输出。
您需要在 pyscripter 中禁用 Pretty print output 选项:
If checked the standard python module pprint is used to format interpreter output.
在选项 > IDE 选项 > Python 解释器.
下找到它
pprint
module 以排序的键顺序输出字典,忽略字典的当前顺序。来自文档:
Dictionaries are sorted by key before the display is computed.
匹配旧的 Python 版本输出不是 hack,因为在 Python 3.6 之前 order depended on insertion and deletion order plus a randomised hash seed.
相反,当输出变得笨拙时,使用 pprint
可以提供更好的输出,方法是使用换行符和缩进,其中标准表示只是将所有内容放在一行中。
你的具体例子并没有真正说明区别,更长的字典会更清楚:
>>> from requests import get
>>> from secrets import token_hex
>>> from pprint import pprint
>>> fortunes = {token_hex(4): get("https://fortuneapi.herokuapp.com/").text for _ in range(5)}
>>> print(repr(fortunes)) # standard REPL output prints the repr() result
{'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be lawyers.\n\t\t-- Tom Wicker\n"\n', '1f08db3c': '"Very few profundities can be expressed in less than 80 characters.\n"\n', '6037e01e': '"The main problem I have with cats is, they\'re not dogs.\n\t\t-- Kevin Cowherd\n"\n', 'b817eaf8': '"New York now leads the world\'s great cities in the number of people around\nwhom you shouldn\'t make a sudden move.\n\t\t-- David Letterman\n"\n', 'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'}
>>> pprint(fortunes) # pprint outputs pretty-printed lines, sorted.
{'1f08db3c': '"Very few profundities can be expressed in less than 80 '
'characters.\n"\n',
'6037e01e': '"The main problem I have with cats is, they\'re not '
'dogs.\n\t\t-- Kevin Cowherd\n"\n',
'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be '
'lawyers.\n\t\t-- Tom Wicker\n"\n',
'b817eaf8': '"New York now leads the world\'s great cities in the number of '
"people around\nwhom you shouldn't make a sudden "
'move.\n\t\t-- David Letterman\n"\n',
'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'}
如果您只是偶尔需要检查字典的特定项目顺序,您可以只启用该选项,并在那些特殊时间使用 print(dictionary)
。
您也可以将 sort_dicts=False
参数传递给 pprint()
,前提是您手动调用它; pprint.pp()
function 甚至将其设为默认值:
>>> from pprint import pp
>>> pp(fortunes)
{'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be '
'lawyers.\n\t\t-- Tom Wicker\n"\n',
'1f08db3c': '"Very few profundities can be expressed in less than 80 '
'characters.\n"\n',
'6037e01e': '"The main problem I have with cats is, they\'re not '
'dogs.\n\t\t-- Kevin Cowherd\n"\n',
'b817eaf8': '"New York now leads the world\'s great cities in the number of '
"people around\nwhom you shouldn't make a sudden "
'move.\n\t\t-- David Letterman\n"\n',
'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'
}
或者您可以要求 PyScripter 项目在其控制台实现中使用该选项。
来自 PyScripter (3.6.4.0) REPL 控制台:
*** Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32. ***
*** Remote Python engine is active ***
>>> d = {}
>>> d['B'] = 12
>>> d['A'] = 10
>>> d['C'] = 34
>>> d
{'A': 10, 'B': 12, 'C': 34}
这个结果让我们相信 Python 对键进行排序并且不保留插入顺序,而从版本 3.6 开始就保证了。
现在让我们在 PyScripter 之外的控制台中 运行 完全相同的 Python 版本:
Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {}
>>> d['B'] = 12
>>> d['A'] = 10
>>> d['C'] = 34
>>> d
{'B': 12, 'A': 10, 'C': 34}
插入顺序全部保留。
为什么输出不同?
在 pyscripter REPL 中,当我不依赖 REPL 提供答案而是使用 print
语句时,我得到了正确的结果:
>>> print(d)
{'B': 12, 'A': 10, 'C': 34}
其中 d
生成的键就好像它们已排序一样:
>>> d
{'A': 10, 'B': 12, 'C': 34}
所以当涉及到字典顺序时,不要相信 pyscripter REPL 输出。
您需要在 pyscripter 中禁用 Pretty print output 选项:
If checked the standard python module pprint is used to format interpreter output.
在选项 > IDE 选项 > Python 解释器.
下找到它pprint
module 以排序的键顺序输出字典,忽略字典的当前顺序。来自文档:
Dictionaries are sorted by key before the display is computed.
匹配旧的 Python 版本输出不是 hack,因为在 Python 3.6 之前 order depended on insertion and deletion order plus a randomised hash seed.
相反,当输出变得笨拙时,使用 pprint
可以提供更好的输出,方法是使用换行符和缩进,其中标准表示只是将所有内容放在一行中。
你的具体例子并没有真正说明区别,更长的字典会更清楚:
>>> from requests import get
>>> from secrets import token_hex
>>> from pprint import pprint
>>> fortunes = {token_hex(4): get("https://fortuneapi.herokuapp.com/").text for _ in range(5)}
>>> print(repr(fortunes)) # standard REPL output prints the repr() result
{'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be lawyers.\n\t\t-- Tom Wicker\n"\n', '1f08db3c': '"Very few profundities can be expressed in less than 80 characters.\n"\n', '6037e01e': '"The main problem I have with cats is, they\'re not dogs.\n\t\t-- Kevin Cowherd\n"\n', 'b817eaf8': '"New York now leads the world\'s great cities in the number of people around\nwhom you shouldn\'t make a sudden move.\n\t\t-- David Letterman\n"\n', 'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'}
>>> pprint(fortunes) # pprint outputs pretty-printed lines, sorted.
{'1f08db3c': '"Very few profundities can be expressed in less than 80 '
'characters.\n"\n',
'6037e01e': '"The main problem I have with cats is, they\'re not '
'dogs.\n\t\t-- Kevin Cowherd\n"\n',
'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be '
'lawyers.\n\t\t-- Tom Wicker\n"\n',
'b817eaf8': '"New York now leads the world\'s great cities in the number of '
"people around\nwhom you shouldn't make a sudden "
'move.\n\t\t-- David Letterman\n"\n',
'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'}
如果您只是偶尔需要检查字典的特定项目顺序,您可以只启用该选项,并在那些特殊时间使用 print(dictionary)
。
您也可以将 sort_dicts=False
参数传递给 pprint()
,前提是您手动调用它; pprint.pp()
function 甚至将其设为默认值:
>>> from pprint import pp
>>> pp(fortunes)
{'a33435f0': '"If reporters don\'t know that truth is plural, they ought to be '
'lawyers.\n\t\t-- Tom Wicker\n"\n',
'1f08db3c': '"Very few profundities can be expressed in less than 80 '
'characters.\n"\n',
'6037e01e': '"The main problem I have with cats is, they\'re not '
'dogs.\n\t\t-- Kevin Cowherd\n"\n',
'b817eaf8': '"New York now leads the world\'s great cities in the number of '
"people around\nwhom you shouldn't make a sudden "
'move.\n\t\t-- David Letterman\n"\n',
'c89994e7': '"I\'m GLAD I remembered to XEROX all my UNDERSHIRTS!!\n"\n'
}
或者您可以要求 PyScripter 项目在其控制台实现中使用该选项。