我有元组/列表的列表 (-1,0,1) (-1,1,0) (-1,2,-1) (-1,-1、2) (0,1,-1)
我需要它们为:(-1,1,0) (-1,2,-1)
我想要(-1,0,1)和(-1,1,0)映射到同一件事。我想到过类似set的东西,但是它将删除我可能在元组中存在的所有重复项。
在生成一个新的元组时说(-1,-1,2),我想执行类似
的检查if (-1,-1,2) in seen:
pass
else:
insert(seen, (-1,-1,2))
为此,我需要数据结构可哈希用于O(1)查找。 有什么想法可以在Python中实现吗?
答案 0 :(得分:0)
您可以对元组进行排序,并使用set
检查重复项,因为元组是可哈希的
a=[(-1, 0, 1) ,(-1, 1, 0), (-1, 2, -1) ,(-1, -1, 2), (0, 1, -1)]
my_set=set()
res=[]
for original_value, sorted_value in zip(a,map(sorted,a)):
if tuple(sorted_value) not in my_set:
res.append(original_value)
my_set.add(tuple(sorted_value))
输出
[(-1, 0, 1), (-1, 2, -1)]
可以使用defaultdict
from collections import defaultdict
d=defaultdict(list)
a=[(-1, 0, 1) ,(-1, 1, 0), (-1, 2, -1) ,(-1, -1, 2), (0, 1, -1)]
res=[]
for original_value, sorted_value in zip(a,map(sorted,a)):
d[tuple(sorted_value)].append(original_value)
输出:
{
(-1, -1, 2): [(-1, 2, -1), (-1, -1, 2)],
(-1, 0, 1): [(-1, 0, 1), (-1, 1, 0), (0, 1, -1)]
}
答案 1 :(得分:0)
您可以使用set
来避免添加映射到同一事物的元素。
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
new_l = []
for i in l:
if set(i) not in [set(j) for j in new_l]:
new_l += [i]
print new_l
它返回[(-1, 0, 1), (-1, 2, -1)]
修改
这错误地将某些元组标记为重复项。这应该可以工作:
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
new_l = list(set([tuple(sorted(i)) for i in l]))
print new_l
答案 2 :(得分:0)
您可以使用collections.Counter
高效地获取列表中每个元组的签名,将Counter
对象的项目映射到冻结集,以使签名变得可哈希化,然后将它们放入一组复制,然后使用Counter.elements()
方法重新创建元组:
from collections import Counter
l = [(-1, 0, 1), (-1, 1, 0), (-1, 2, -1), (-1, -1, 2), (0, 1, -1)]
[tuple(Counter(dict(i)).elements()) for i in {frozenset(Counter(t).items()) for t in l}]
这将返回:
[(0, -1, 1), (-1, -1, 2)]