最近我注意到,当我转换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)
我的问题是 -
Sve*_*ach 90
A set是无序数据结构.
不要使用set,而是collections.OrderedDict:
>>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210])
>>> b = collections.OrderedDict.fromkeys([6, 20, 1])
>>> collections.OrderedDict.fromkeys(x for x in a if x not in b)
OrderedDict([(2, None), (210, None)])
Run Code Online (Sandbox Code Playgroud)
请注意,顺序b无关紧要,因此它可以是任何可迭代的,但它应该是一个支持O(1)成员资格测试的可迭代.
编辑:上面的答案假定您希望能够对所有正在发生的集合执行(有序)集合操作,特别是对前一个集合操作的结果.如果没有必要,您可以简单地为某些集合使用列表,为其他集合使用集合,例如
>>> a = [1, 2, 20, 6, 210]
>>> b = set([6, 20, 1])
>>> [x for x in a if x not in b]
[2, 210]
Run Code Online (Sandbox Code Playgroud)
这会丢失顺序b,不允许快速成员资格测试a和结果.集允许快速成员资格测试,列表保持顺序.如果您在同一个集合中需要这两个功能,请使用collections.OrderedDict.
Tig*_*222 39
在Python 3.6中, Python 2和3还有另一个解决方案:set()现在应该保持顺序,但是
>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]
Run Code Online (Sandbox Code Playgroud)
小智 19
通过以下功能删除重复项并保留顺序
def unique(sequence):
seen = set()
return [x for x in sequence if not (x in seen or seen.add(x))]
Run Code Online (Sandbox Code Playgroud)
lve*_*lla 16
回答第一个问题,集合是针对集合操作优化的数据结构.像数学集一样,它不强制执行或维护元素的任何特定顺序.集合的抽象概念不强制执行顺序,因此不需要实现.当您从列表创建集合时,Python可以自由地更改元素的顺序,以满足其用于集合的内部实现的需要,从而能够有效地执行集合操作.
Ale*_*rdi 15
你可以用一行代码删除重复的值并保持插入的列表顺序,Python 3.8.2
mylist = ['b', 'b', 'a', 'd', 'd', 'c']
结果 = list({value:"" for mylist 中的值})
打印(结果)
>>> ['b'、'a'、'd'、'c']
结果 = 列表(dict.fromkeys(mylist))
打印(结果)
>>> ['b'、'a'、'd'、'c']
pyl*_*ang 14
在 Python 中,只直接实现了集合。我们可以使用常规的 dict 键(3.7+)模拟 oset 。
给定的
a = [1, 2, 20, 6, 210, 2, 1]
b = {2, 6}
Run Code Online (Sandbox Code Playgroud)
代码
oset = dict.fromkeys(a).keys()
# dict_keys([1, 2, 20, 6, 210])
Run Code Online (Sandbox Code Playgroud)
演示
删除重复项,保留插入顺序。
list(oset)
# [1, 2, 20, 6, 210]
Run Code Online (Sandbox Code Playgroud)
dict 键上的类似设置的操作。
oset - b
# {1, 20, 210}
oset | b
# {1, 2, 5, 6, 20, 210}
oset & b
# {2, 6}
oset ^ b
# {1, 5, 20, 210}
Run Code Online (Sandbox Code Playgroud)
细节
注意:无序结构不排除有序元素。相反,不保证维持秩序。例子:
assert {1, 2, 3} == {2, 3, 1} # sets (order is ignored)
Run Code Online (Sandbox Code Playgroud)
assert [1, 2, 3] != [2, 3, 1] # lists (order is guaranteed)
Run Code Online (Sandbox Code Playgroud)
人们可能会很高兴地发现列表和多集(mset) 是两种更迷人的数学数据结构:
概括
Container | Ordered | Unique | Implemented
----------|---------|--------|------------
set | n | y | y
oset | y | y | n
list | y | n | y
mset | n | n | n*
Run Code Online (Sandbox Code Playgroud)
*多重集可以间接模拟collections.Counter(),一个类似字典的多重性(计数)映射。
如其他答案中所述,集合是不保留元素顺序的数据结构(和数学概念)-
但是,通过使用集合和字典的组合,您可以实现任何您想要的 - 尝试使用这些片段:
# save the element order in a dict:
x_dict = dict(x,y for y, x in enumerate(my_list) )
x_set = set(my_list)
#perform desired set operations
...
#retrieve ordered list from the set:
new_list = [None] * len(new_set)
for element in new_set:
new_list[x_dict[element]] = element
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
99355 次 |
| 最近记录: |