【问题标题】:what is deciding the order of the set elements in this python 3 code? [duplicate]什么决定了这个 python 3 代码中集合元素的顺序? [复制]
【发布时间】:2018-11-07 10:43:12
【问题描述】:

为什么元素的顺序只有通过函数调用才会改变?是什么决定了这个顺序?

# test_set_order.py
def unpack(input):
    print('input is {}'.format(input))
    result = []
    for i in input:
        result.extend(i)
    return result

print(unpack({'A', 'B'}))

执行上面的脚本会产生不同的输出:

$ python test_set_order.py
input is {'B', 'A'}
['B', 'A']
$ python test_set_order.py
input is {'B', 'A'}
['B', 'A']
$ python test_set_order.py
input is {'A', 'B'}
['A', 'B']
$ python test_set_order.py
input is {'B', 'A'}
['B', 'A']
$ python test_set_order.py
input is {'A', 'B'}
['A', 'B']
$ python test_set_order.py
input is {'A', 'B'}
['A', 'B']

这是python 3.6.5。在 python 2.7.13 上,您总是得到相同的订单

似乎只有在函数调用之后才会改变顺序。它以前不会发生:

>>> bla = {'A','B'}; print(bla)
{'A', 'B'}
>>> bla = {'A','B'}; print(bla)
{'A', 'B'}
>>> bla = {'A','B'}; print(bla)
{'A', 'B'}
>>> bla = {'A','B'}; print(bla)
{'A', 'B'}
>>> bla = {'A','B'}; print([i for i in bla])
['A', 'B']
>>> bla = {'A','B'}; print([i for i in bla])
['A', 'B']
>>> bla = {'A','B'}; print([i for i in bla])
['A', 'B']
>>> bla = {'A','B'}; print([i for i in bla])
['A', 'B']
>>> bla = {'A','B'}; print([i for i in bla])
['A', 'B']

更新:

似乎它与散列有关,它是在解释器启动时决定的。这足以重现:

$ python -c "print({'A', 'B'})"
{'B', 'A'}
$ python -c "print({'A', 'B'})"
{'A', 'B'}

'A'.__hash__()) 的值每次在python 3 上都会改变

【问题讨论】:

  • 散列决定了顺序,但是这些都是无证的,不能保证实现细节,如果你想要一个特定的顺序,不要使用集合
  • @Chris_Rands 这与您链接的问题不同。为什么顺序只在函数调用期间发生变化?而不是在其他示例中
  • 看我的第二个骗子stackoverflow.com/questions/49896202/…,原因是Python 3默认启用哈希随机化,你可以通过PYTHONHASHSEED关闭它
  • 酷,谢谢!那个更好:)

标签: python python-3.x set python-3.6


【解决方案1】:

集合在 Python 中是无序的。你不应该期望一致性。

举个简单的例子,在 Python3 的 REPL (python -i),

>> x={3,1,2}
>>> print(x)
{1, 2, 3}

Python2 也是如此

>>> x={3,2,1}
>>> print(x)
set([1, 2, 3])

它们也不是简单的自动排序,就像在这个 Python3 示例中一样:

>>> x={3,('a','b'), 'x',0.11,'y',None, 'z',4.11,('c','d')}
>>> print(x)
{0.11, 3, 'y', 4.11, ('c', 'd'), 'x', ('a', 'b'), None, 'z'}

如果您希望它们保持插入的顺序,请使用 OrderedSet(如 this)或重复使用 OrderedDict

【讨论】:

  • OrderedSet 不是标准库中的东西
  • 已添加说明
【解决方案2】:

因为by definition 一个集合是一个无序对。如果您想订购它们,请使用list

只需替换:

{'A', 'B'}

与:

['A', 'B']

这是因为集合是使用花括号 {} 创建的,而列表是使用括号 [] 定义的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多