最近我注意到,当我转换list到set元素的顺序发生变化,由字符排序.
考虑这个例子:
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
Run Code Online (Sandbox Code Playgroud)
我的问题是 -
我知道Python中的集合是无序的,但我对它们显示的"顺序"感到好奇,因为它似乎是一致的.它们似乎每次都以相同的方式乱序:
>>> set_1 = set([5, 2, 7, 2, 1, 88])
>>> set_2 = set([5, 2, 7, 2, 1, 88])
>>> set_1
set([88, 1, 2, 5, 7])
>>> set_2
set([88, 1, 2, 5, 7])
Run Code Online (Sandbox Code Playgroud)
......和另一个例子:
>>> set_3 = set('abracadabra')
>>> set_4 = set('abracadabra')
>>> set_3
set(['a', 'r', 'b', 'c', 'd'])
>>>> set_4
set(['a', 'r', 'b', 'c', 'd'])
Run Code Online (Sandbox Code Playgroud)
我只是好奇为什么会这样.有帮助吗?
我最近惊讶地发现,虽然 dicts 保证在 Python 3.7+ 中保留插入顺序,但集合不是:
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d['d'] = 4
>>> d
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
Run Code Online (Sandbox Code Playgroud)
>>> s = {'a', 'b', 'c'}
>>> s
{'b', 'a', 'c'}
>>> s.add('d')
>>> s
{'d', 'b', 'a', 'c'}
Run Code Online (Sandbox Code Playgroud)
这种差异的基本原理是什么?导致 Python 团队更改 dict 实现的相同效率改进也不适用于集合吗?
我不是在寻找指向有序集实现的指针或使用 dicts 作为集合的替代品的方法。我只是想知道为什么 Python 团队没有在他们为 dicts 这样做的同时使内置集保留顺序。
在Python中,当你想使用列表作为某些字典的键时,你可以把它们变成元组,这些元组是不可变的,因此是可以删除的.
>>> a = {}
>>> a[tuple(list_1)] = some_value
>>> a[tuple(list_2)] = some_other_value
Run Code Online (Sandbox Code Playgroud)
当您想要将set对象用作某些字典的键时,也会发生同样的情况- 您可以构建一个冷冻集,这也是不可变的,因此是可清除的.
>>> a = {}
>>> a[frozenset(set_1)] = some_value
>>> a[frozenset(set_2)] = some_other_value
Run Code Online (Sandbox Code Playgroud)
但似乎对于字典没有等价物.
我想到的第一个想法(最终发现它很糟糕)是str(some_dict)用作关键.但是,字典总是使用不同的散列函数,因此相同字典的字符串可能不同.
是否有任何解决方法称为良好实践,或者是否有人有其他想法如何使用类字典对象作为其他词典的键?
考虑以下示例:
import itertools
import numpy as np
a = np.arange(0,5)
b = np.arange(0,3)
c = np.arange(0,7)
prods = itertools.product(a,b,c)
for p in prods:
print(p)
Run Code Online (Sandbox Code Playgroud)
这将按以下顺序迭代产品:
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 0, 3)
(0, 0, 4)
(0, 1, 0)
Run Code Online (Sandbox Code Playgroud)
但我更愿意按总和的顺序给出产品,例如
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(1, 0, 0)
(0, 1, 1)
(1, 0, 1)
(1, 1, 0)
(0, 0, 2)
Run Code Online (Sandbox Code Playgroud)
如何在不将所有组合存储在内存中的情况下实现这一目标?
注意: a b和c始终是范围,但不一定具有相同的最大值。当两个乘积之和相等时,也没有二级排序,即(0,1,1)等于(2,0,0)。