Python:元组列表:比较所有元组并检索元组的元素不等于任何其他元组的元组

Posted

技术标签:

【中文标题】Python:元组列表:比较所有元组并检索元组的元素不等于任何其他元组的元组【英文标题】:Python: List of tuples: compare all tuples and retrive tuples where the elements of tuples are not equal to any other tuple 【发布时间】:2015-05-05 17:09:57 【问题描述】:

我有一个这样的元组列表:

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

查询列表的输出将返回四个元组,因为元组的元素 2(实际上是元素 3)最多有四种可能性。示例输出:

[(408, 2, 5), (181, 3, 2), (907, 10, 6), (100, 11, 1)]

我尝试过使用 while 循环并分别遍历列表和元组的每个元素以删除列表的相应元素或创建单独的列表,但这种方法没有考虑所有可能性并且感觉错误:

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

我也研究过集合,但据我所知,它只会删除元组的重复项。

谢谢。

【问题讨论】:

如果(408, 2, 5)(408, 2, 2) 都出现在原始列表中,为什么(408, 2, 5) 在输出中?根据您的描述,它不应​​该是 4082 并不是唯一的。 (408, 2, 5)(408, 2, 2)的第一个元素为408,第二个元素为2,那么(408, 2, 5)如何包含在输出中? 事实上,进一步查看原始列表,没有一个输出符合标准。 【参考方案1】:

您可以使用双循环比较所有元组,并使用列表推导来实现可伸缩性:

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

【讨论】:

【参考方案2】:

如果您想要具有唯一值的元组,而不是与实际输入元组之一相对应的元组(因为您声明“...返回元组中的每个元素对所有其他元组。”)。

>>> list(zip(*(set(zz) for zz in zip(*z))))
[(408, 2, 1), (907, 3, 2), (276, 10, 5), (181, 11, 6)]

虽然很有趣,但出于显而易见的原因,我很难推荐它。


解释发生了什么:

zip(*z)

这“反转”了元组列表,所以从 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。

【讨论】:

以上是关于Python:元组列表:比较所有元组并检索元组的元素不等于任何其他元组的元组的主要内容,如果未能解决你的问题,请参考以下文章

Python中的元组(Tuple)

拆分两个元素的元组并添加到熊猫数据框[重复]

如何从具有子元组的元组创建列表?

Python - 验证列表中的元组具有相同的长度

Python的元组列表截取

遍历 pandas 数据框中的行并匹配列表中的元组并创建一个新的 df 列