从列表中删除重复的无序元组
Posted
技术标签:
【中文标题】从列表中删除重复的无序元组【英文标题】:Remove duplicate unordered tuples from list 【发布时间】:2018-02-02 20:18:36 【问题描述】:在元组列表中,我只想拥有一个元组的一个副本,它可能是 (x, y) 或 (y, x)。
所以,在:
# pairs = list(itertools.product(range(3), range(3)))
pairs = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
结果应该是:
result = [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)] # updated pairs
这个元组列表是使用itertools.product()
生成的,但我想删除重复项。
我的工作解决方案:
pairs = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
result = []
for pair in pairs:
a, b = pair
# reordering in increasing order
temp = (a, b) if a < b else (b, a)
result.append(temp)
print(list(set(result))) # I could use sorted() but the order doesn't matter
如何改进?
【问题讨论】:
您的解决方案有什么问题?您希望改进代码的哪些方面? @ChrisMartin 速度改进 > 就地删除 > 简洁代码 @AjitZero,这些看起来像坐标。那是他们起源的地方吗?我问的原因是稀疏矩阵擅长存储和操作此类数据。我在下面提供了一个利用这一点的解决方案。 @jp_data_analysis 就我而言,没有。不过感谢您分享! 【参考方案1】:你可以使用combinations_with_replacement
combinations_with_replacement() 的代码也可以表示为 product() 在过滤了元素未按排序顺序(根据它们在输入池中的位置)的条目后的子序列
import itertools
pairs = list(itertools.combinations_with_replacement(range(3), 2))
print(pairs)
>>> [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]
【讨论】:
【参考方案2】:edit 我刚刚意识到,您的解决方案与我的解决方案相匹配。你在做什么就好了。如果您需要为一个非常大的列表执行此操作,那么您可能需要考虑其他一些选项,例如键值存储。
如果您需要更多地以编程方式删除欺骗,那么您可以使用如下函数:
def set_reduce(pairs):
new_pairs = set([])
for x,y in pairs:
if x < y:
new_pairs.add((x,y))
else:
new_pairs.add((y,x))
return new_pairs
运行这个结果
>>>set_reduce(pairs)
set([(0, 1), (1, 2), (0, 0), (0, 2), (2, 2), (1, 1)])
【讨论】:
【参考方案3】:这是一种依赖于sparse matrices 的解决方案。这样做的原因如下:
矩阵中的条目不能包含两个值。因此,保证了唯一性。
选择上面的三角形可确保 (0, 1) 优于 (1, 0),并且不可能同时包含两者。
import numpy as np
from scipy.sparse import csr_matrix, triu
lst = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1),
(1, 2), (2, 0), (2, 1), (2, 2)]
# get row coords & col coords
d1, d2 = list(zip(*lst))
# set up sparse matrix inputs
row, col, data = np.array(d1), np.array(d2), np.array([1]*len(lst))
# get upper triangle of matrix including diagonal
m = triu(csr_matrix((data, (row, col))), 0)
# output coordinates
result = list(zip(*(m.row, m.col)))
# [(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]
【讨论】:
以上是关于从列表中删除重复的无序元组的主要内容,如果未能解决你的问题,请参考以下文章