我有两个列表(大小相同)
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])
但我想知道是否有更好的解决方案
答案 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
是一个布尔表达式,因此结果将是True
或False
。在Python中,True
为1
,False
为0
。
>>> 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))