一个Python用整数作为键自然排序吗?

时间:2013-12-04 23:15:05

标签: python dictionary integer key sorted

如果我创建一个使用整数作为键的Python dict,我可以安全地假设迭代dict将根据键值按顺序检索项目吗?

即。将

my_dict = {}
for x in range(0,100):
  my_dict[x] = str(x)

for item in my_dict.items():
  print item

总是导致按键值的顺序打印列表?

6 个答案:

答案 0 :(得分:11)

简而言之,没有。我打赌你注意到字典使用键的哈希作为数组的索引,并且因为ints哈希到它们自己的值,你推断如果它们的键是整数,插入的值将按键顺序结束。虽然该陈述的前两部分是真实的,但推论并非如此,即使是无证的副作用。 dict键是从键的哈希中派生,但不是完整的哈希。这意味着即使使用整数键,您仍然可以进行无序插入,因为2个值可能在同一位置发生冲突(或者甚至具有“乱序”散列导出的值),因此最终会导致键无序插入字典。

基本上,将它视为dict的内部存储阵列中的索引,它是来自密钥哈希的一些低位比特。仅仅因为一个数字大于另一个数字并不意味着从它的截断低阶位构建的值将更大,甚至不同。

答案 1 :(得分:6)

不,无论关键值如何,Python词典都没有固有的排序。如果您需要订购,请坚持使用数组或列表,或者更好 - 请查看pandas,这将允许类似的字典功能按键值调用,以及许多其他强大功能(http://pandas.pydata.org/pandas-docs/stable/10min.html )。

答案 2 :(得分:2)

如果您想以有序的方式进行迭代,请

No, you cannot. 始终排序。

答案 3 :(得分:2)

我不这么认为。您必须使用collections.OrderedDict才能确保订购。但是,这将按照添加顺序对条目进行排序。

答案 4 :(得分:1)

Python字典没有以任何有意义的方式排序;它们是哈希表。

Python附带了collections.OrderedDict,但这按插入顺序排序,而不是键的顺序。

这是两个类似字典的模块,按键排序:

https://pypi.python.org/pypi/treap/

https://pypi.python.org/pypi/red-black-tree-mod/

有人说,treaps平均比红黑树快,但红黑树的操作时间标准偏差较小。其他人质疑这一点,尽管在我的测试中前者证明了这一点。

Treaps和红黑树在O(logn)时间内几乎可以完成所有操作,但不断保持按键顺序。对于大多数操作,Python字典都是O(1)。但是,按顺序获取所有键对于treaps和红黑树都是O(n),而对于字典来说是O(nlogn)。

你什么时候应该使用哪个?

  1. 如果你在一个循环中进行排序,你可能会更好地接受一次治疗 或红黑树。
  2. 如果您在程序结束时进行了一次排序, 你最好用list_ = list(dict_); list_.sort()
  3. 如果您保留输入的顺序,例如从配置文件中 或者其他什么,你最好用OrderedDict。
  4. HTH

答案 5 :(得分:0)

我参加聚会很晚,但是如果您像我一样,通过[您最喜欢的搜索引擎]偶然浏览了此页面,那么我想成为向您发送好消息的人:

虽然Python字典永远不会自然排序,但像使用它们一样琐碎。假设您的键实际上是整数,只需将您喜欢的字典D传递给内置的sorted就像这样:

for index, item in sorted(D.items()):
    print("index:", index, "item:", item)

D.items()返回带有dict_items方法的类__iter__,该方法在被forin语句调用时,返回一个迭代器,产生键值对,可以像其他任何可迭代对象一样进行迭代。

sorted接收迭代器并返回一个列表,因此,如果D = {1: "alpha", 3: "charlie", 2: "bravo"},则sorted返回的是排序后的列表[(1, "alpha"), (2, "bravo"), (3, "charlie")]

还可以按特定元素进行排序:

sorted(D.items(), key=lambda x: x[1])

或者通过其他一些任意的甚至不确定的排序标准:

sorted(D.items(), lambda _: random.randint(0, 100))

从dict构造列表的方法是在时间和空间上执行操作 O(n),Python的排序算法Timsort非常有效( O(n 一般情况下记录 n)),因此在绝大多数实际使用案例中,运行时性能都不值得担心。