如何在Python中统一以下列表:
all_the_ways = [(5,), (2, 2, 1), (2, 1, 2), (2, 1, 1, 1), (1, 2, 2),\
(1, 2, 1, 1), (1, 1, 2, 1), (1, 1, 1, 2), (1, 1, 1, 1, 1)]
所需的输出是:
[(5,), (2, 2, 1), (2, 1, 1, 1), (1, 1, 1, 1, 1)]
即。我需要摆脱具有相同数字但不同顺序的元组。
我试过
set(all_the_ways)
但它只转置元素。
当我做的时候
list(map(set, all_the_ways))
事情变得更糟:
[{5}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1}]
换句话说,我需要将内部元组转换为允许多个相等项目的集合(set
不适合),并且元素的排列不会改变集合本身(有点)比如C ++' multiset
)
答案 0 :(得分:5)
这个怎么样:
list(set(tuple(sorted(s)) for s in all_the_ways))
输出:
[(1, 2, 2), (5,), (1, 1, 1, 1, 1), (1, 1, 1, 2)]
它会破坏每个元组的顺序。我认为这并不重要,因为包含相同数字集的元组在您的情况下被认为是相同的。这意味着,最后,输出列表可能包含不在原始输入中的元组,例如(归功于@thefourtheye):
all_the_ways = [(2, 1, 2), (2, 2, 1)]
# Output: [(1, 2, 2)]
这可能是也可能不是问题,如果是,您可以使用其他优秀答案中已经提到的更强大的解决方案。
答案 1 :(得分:3)
使用collections.Counter()标识唯一的多重集:
>>> from collections import Counter
>>> all_the_ways = [(5,), (2, 2, 1), (2, 1, 2), (2, 1, 1, 1), (1, 2, 2),\
(1, 2, 1, 1), (1, 1, 2, 1), (1, 1, 1, 2), (1, 1, 1, 1, 1)]
>>> result = []
>>> seen = set()
>>> for tup in all_the_ways:
key = tuple(sorted(Counter(tup).items())) # unique signature
if key not in seen:
result.append(tup)
seen.add(key)
>>> result
[(5,), (2, 2, 1), (2, 1, 1, 1), (1, 1, 1, 1, 1)]
答案 2 :(得分:2)
如果订单无关紧要,您可以使用此
from collections import Counter
>>> {frozenset(Counter(tup).items()):tup for tup in data}.values()
# [(1, 2, 2), (1, 1, 1, 2), (1, 1, 1, 1, 1), (5,)]
如果您想维护订单,
from collections import Counter, OrderedDict
OrderedDict([frozenset(Counter(tup).items()),tup] for tup in data).values()
# [(5,), (1, 2, 2), (1, 1, 1, 2), (1, 1, 1, 1, 1)]
在我们依赖frozenset
的两个解决方案中,因为set
个对象不可编辑,因为它们是可变的。在第一种情况下,我们构造一个字典,其中数字的频率(用Counter
确定)作为键,当前元组作为对应的值。字典构造完成后,我们将获取与元组相对应的所有值。
在第二种情况下,我们只需使用OrderedDict
来维护订单。
答案 3 :(得分:1)
可能是这个?:
result = {tuple(sorted(x)) for x in all_the_ways}
答案 4 :(得分:1)
尝试
from collections import OrderedDict
print OrderedDict.fromkeys(map(lambda x: tuple(sorted(x)), all_the_ways)).keys()
或
print set(map(lambda x: tuple(sorted(x)), all_the_ways))
答案 5 :(得分:0)
我认为如果它们包含相同的值,则认为两个元素“相等”,无论顺序如何。
因此,您可以通过对每个元组进行“规范化”,将其转换回元组(以便它们可以播放),并再次使用set
删除重复项:
set( tuple(sorted(tup)) for tup in all_the_ways )
您还可以使用OrderedSet
代替set
来保留原始的“外部”订单。