我有一个像这样的元组列表:
z = [(408, 2, 5), (408, 2, 2), (181, 2, 2), (181, 2, 5), (907, 2, 6), (907, 2, 1), (276, 2, 5), (276, 2, 2), (100, 2, 1), (100, 2, 6), (408, 3, 5), (408, 3, 2), (181, 3, 2), (181, 3, 5), (907, 3, 6), (907, 3, 1), (276, 3, 5), (276, 3, 2), (100, 3, 6), (100, 3, 1), (907, 10, 6), (907, 10, 1), (100, 10, 1), (100, 10, 6), (907, 11, 6), (907, 11, 1), (100, 11, 6), (100, 11, 1)]
我要做的是将所有元组相互比较并返回元组中每个元素对于所有其他元组唯一的元组。
在上面的列表中,任何元组的第一个元素都可以具有值408, 181, 907, 276 or 100
第二个元素的值为2, 3, 10 or 11
和第三个元素值1, 2, 5 or 6
。
查询列表的输出将返回四个元组,因为元组的元素二(实际上元素3)最多有四种可能性。示例输出:
[(408, 2, 5), (181, 3, 2), (907, 10, 6), (100, 11, 1)]
我尝试使用while循环并逐步遍历列表和元组的每个元素以删除列表中的相应元素或创建单独的列表,但这种方法并未考虑所有可能性并且感觉不对:< / p>
i = 0
j = 1
try:
while i < len(z):
if z[i][0] == z[j][0] or z[i][1] == z[j][1] or z[i][2] == z[j][2]:
del z[j]
else:
j += 1
i += 1
except:
pass
我也研究了集合但是从我收集的内容中它只会删除重复的元组。
感谢。
答案 0 :(得分:1)
如果您希望元组具有唯一值,而不是与实际输入元组之一相对应的元组(因为您声明&#34; ...返回元组中每个元素的元组),这个单行可以执行此操作所有其他元组都是独一无二的。&#34;)。
>>> list(zip(*(set(zz) for zz in zip(*z))))
[(408, 2, 1), (907, 3, 2), (276, 10, 5), (181, 11, 6)]
虽然很有趣,但我很难推荐这个原因。
解释发生的事情:
zip(*z)
这&#34;倒置&#34;元组列表,从28 x 3开始,这是3 * 28。
(set(zz) for zz in zip(*z))
过滤每个len-28元组中的唯一值。这导致:
[{408, 907, 276, 181, 100}, {2, 3, 10, 11}, {1, 2, 5, 6}]
现在我们需要从中创建元组。我们可以再次使用zip
:
zip(*(set(zz) for zz in zip(*z)))
幸运的是,zip
在第一个元素耗尽时停止,即4-len元组;它并不要求所有元组的长度都为5。
答案 1 :(得分:0)
您可以使用双循环比较所有元组,并使用列表推导来实现可伸缩性:
i = 0
while i < len(z):
j = i+1
while j < len(z):
if any([z[i][n]==z[j][n] for n in range(len(z[0]))]):
del z[j] # Shift all values, so no need to update j
else:
j += 1
i += 1