获取两个不同列表中相同索引处的一对值的出现次数

时间:2015-05-07 11:43:08

标签: python list python-2.7

我有两个列表(大小相同)

a = [0, 0, 1, 0, 0, 1, 1, 0]
b = [2, 2, 0, 2, 1, 1, 0, 2]

假设当列表'a'中的值'0'匹配时,我需要获得列表'b'中值'2'的出现次数。例如,在之前的两个列表中,我希望得到4(我在'a'中的值为'0',在'b'中的值为'2'同时在位置0,1,3,7)

一种方法:

len([x for x,y in zip(a,b) if x==0 and y==2])

但我想知道是否有更好的解决方案

4 个答案:

答案 0 :(得分:3)

如果你的阵列(也许你的意思是列表)会更长,那么使用itertools.izip会更好,因为zip将创建来自a的相应元素的元组列表和b

>>> a = [0, 0, 1, 0, 0, 1, 1, 0]
>>> b = [2, 2, 0, 2, 1, 1, 0, 2]
>>> from itertools import izip
>>> sum(x == 0 and y == 2 for x, y in izip(a, b))
4

此处,x == 0 and y == 2是一个布尔表达式,因此结果将是TrueFalse。在Python中,True1False0

>>> False == 0
True
>>> True == 1
True

sum函数对所有这些函数进行求和并给出结果。

另请注意,我们未将列表传递给sum[]不存在)。这意味着我们正在传递一个生成器表达式。 sum将调用生成器表达式来获取值。因此,不会像len解决方案那样创建临时列表,但会根据需要检索值。阅读有关生成器和生成器表达式的更多信息,here

因此,如果您的列表很长(因为它避免了任何临时列表构造),这个解决方案将非常有效并且非常有用。

答案 1 :(得分:2)

如果您的列表不是很大,请使用list.count:

a = [0, 0, 1, 0, 0, 1, 1, 0]
b = [2, 2, 0, 2, 1, 1, 0, 2]
print(zip(a,b).count((0,2)))

对于Python 3,zip返回一个迭代器,你必须使用list(zip(..))来生成一个列表。如果要计算多个变体,collections.Counter可以这样做:

>>> print collections.Counter(zip(a,b))
Counter({(0, 2): 4, (1, 0): 2, (0, 1): 1, (1, 1): 1})

另外,知道Python的True和False有数值1和0(事实上,bool是int的子类型),我们可以简单地对生成器求和:

sum(pair==(0,2) for pair in zip(a,b))

答案 2 :(得分:1)

嗯,风格方面,这似乎非常pythonic和可理解,所以对我来说这是足够好。

性能方面,你需要迭代两者,所以我不认为你是。唯一的改进是使用izip而不是构建匹配元素的实际列表。有点像:

from itertools import izip
sum(1 for x,y in izip(a,b) if x==0 and y==2)

可行。 无论如何,只有在需要性能的情况下才能改进。 (顺便说一句,你忘记了例子中元素之间的逗号)

答案 3 :(得分:0)

sum(x == 0 and y == 2 for x, y in zip(a, b))