python 3.6与旧版本中的字典顺序
Posted
技术标签:
【中文标题】python 3.6与旧版本中的字典顺序【英文标题】:Dict order in python 3.6 vs older 【发布时间】:2017-11-04 11:14:07 【问题描述】:当我通过tabulate
运行它时,我需要按照这个确切的顺序(访客团队、访客评级、主队、主场评级、预期获胜者、保证金)打印出这段代码。
final_dict = 'Visitor Team': visitor_team, 'Visitor Rating': visitor_rating, 'Home Team': home_team,
'Home Rating': home_rating, 'Expected Winner': expected_winner, 'Margin': expected_winner_diff
print(tabulate(final_dict, headers="keys", floatfmt=".2f", tablefmt="fancy_grid"))
我一直在学习和使用 Python 3.6,但我不知道的是,现在订购了 3.6 中的 dicts,所以这实际上按我的意图打印出来。我猜 Python 3.6 正好给了我我需要的东西,这只是运气不好!
但是我在另一台计算机上安装了 Python 3.5,但并没有像我想要的那样打印出来。我一直在阅读有关orderdicts 的信息,但我不确定如何使用它。我是否需要先将 final_dict 声明为空,然后按我需要的键顺序对其进行迭代?
【问题讨论】:
字典不按顺序存储键。如果你想保持顺序,你应该使用一个列表。 您没有提供函数tabulate
,但这就是打印完成的地方。这里的重要问题是,tabulate
如何通过final_dict
的元素递增?它如何使用headers
的值来控制打印顺序?它如何知道字典的哪个元素匹配哪个标题?我认为您应该查看tabulate
以了解它是如何工作的。否则无法保证更改为 OrderedDict 会解决您的问题。
@PaulCornelius 这些都是好点。 tabulate
是一个用于打印表格输出的包:pypi.python.org/pypi/tabulate 我没有写它,所以我不确定它的“内部”是如何工作的。
文档pypi.python.org/pypi/tabulate 说制表的第一个参数可以是列表的列表。这似乎是控制列顺序的唯一可靠方法。由于这对您很重要,因此我会将您的数据转换为列表列表,然后再将其传递给列表。
相关***.com/questions/39980323/…
【参考方案1】:
Python 3.6 中的字典是有序的,但该功能被视为您不应依赖的实现细节(除了**kwargs
等少数特定情况)。如果您确实需要特定订单,则应改用collections.OrderedDict
。您可以使用按所需顺序排列的key, value
元组列表构建一个:
from collections import OrderedDict
finaldict = OrderedDict([('Visitor Team', visitor_team),
('Visitor Rating', visitor_rating),
('Home Team', home_team),
('Home Rating', home_rating),
('Expected Winner', expected_winner),
('Margin', expected_winner_diff),
])
OrderedDict
在大多数方面与普通的dict
一样,除了具有不同的repr
和一些其他方法。您可以在the docs 阅读更多相关信息。
在 Python 3.6+ 中,如果您的键字符串是有效的标识符(例如 OrderedDict(Margin=expected_winner_diff)
),您还可以对构造函数使用关键字参数。与普通dict
s 的顺序不同,关键字的顺序保证被保留(不是实现细节)。但是,这不是向后兼容的(无论如何也不能用于您的非标识符键)。
但可能值得考虑的是,如果您需要非常具体的数据顺序,字典可能不是存储数据的最佳类型。我看到您使用的 tabulate
函数来自库,并且根据文档,它接受许多不同格式的数据。我可能只是将列数据列表传递给它,并分别给它标题:
data = [visitor_team, visitor_rating, home_team,
home_rating, expected_winner, expected_winner_diff]
headers = ["Visitor Team", "Visitor Rating", "Home Team",
"Home Rating", "Expected Winner", "Margin"]
print(tabulate(data, headers=headers, floatfmt=".2f", tablefmt="fancy_grid"))
(请注意,我没有实际测试过该代码,因为我的系统上没有 tabulate
库。但它至少应该接近工作。)
【讨论】:
文档说data
必须是二维数据类型,例如列表列表或列表字典。一个简单的列表是行不通的。我猜 OP 的原始代码可以工作,因为他所有的字典值实际上都是列表。
@PaulCornelius 是的,这是正确的。所有这些都存储为列表。我会玩弄我所拥有的,看看我能想出什么。
我最终只是将我的 finaldict 转换为一个列表。我认为只处理列表而不是弄乱让orderdict工作要容易得多。谢谢你们的帮助!以上是关于python 3.6与旧版本中的字典顺序的主要内容,如果未能解决你的问题,请参考以下文章
Python 3.6 和 Python 3.5 中字典顺序之间的差异 [重复]