3

使用时是否有一种优雅或 Pythonic 的方式来排除包含重复值的条目zip

举个例子:

>>> list1 = [0, 1]
>>> list2 = [0, 2]
>>> zip(list1, list2)
[(0, 0), (1, 2)]

我想只有第二个元素[(1, 2)]。目前,我做

[x for x in zip(list1, list2) if len(set(x)) == len(x)]

但这感觉有点乏味。有一个更好的方法吗?


编辑:我如何将其扩展到一般情况下,其中有两个以上的列表?

>>> list1 = [0, 1]
>>> list2 = [0, 2]
>>> list3 = [0, 3]
>>> ...
>>> zip(list1, list2, list3, ...)

如果任何条目包含任何重复值,则应将其丢弃(并非元组中的每个值都必须相等)。

4

3 回答 3

7

关于什么

[(x,y) for (x,y) in zip(list1, list2) if x != y]

一般情况:

[x for x in zip(list1, list2, ... listn) if not all(z == x[0] for z in x[1:])]

这会找到每个元素都相等的重复项。如果只需要一对等于重复计数,则可以使用您在问题中已经提到的 set 方法,前提是您具有可散列类型。如果你有不可散列的类型,识别重复的(有趣的)问题已经在这里回答过。

于 2013-04-26T15:04:35.497 回答
2

您只有 2 值元组,因此您可以将第一个值与第二个值进行比较。列表理解是最好的选择:

[x for x in zip(list1, list2) if x[0] != x[1]]

对于一般情况,如果您的值都是可散列的,那么您已经有了最佳选择。

如果您有不可散列的类型,您需要已经对“唯一”处理进行特殊处理,所以这超出了这里的范围。

于 2013-04-26T15:04:14.823 回答
1

all恕我直言,这是另一种更清楚地表达代码意图的方式:

[x for x in zip(list1, list2) if not all(x[0] == rest for rest in x)]

这样做的好处是它适用于任意大小的元组(不仅仅是两个元素,你可以这样做zip(list1, list2, list3)),并且它使用生成器表达式,因此它不会创建额外的列表、集合等。

于 2013-04-26T15:14:24.117 回答