[英]How to compare corresponding positions in a list?
I have N number of list of same length. 我有N个相同长度的列表。 How can I compare these lists in corresponding position and output the number of positions where they all match?
如何在相应位置比较这些列表并输出它们全部匹配的位置数?
For example: 例如:
A=[1,0,1,1]
B=[1,1,1,1]
C=[1,0,1,0]
comparison of these three list would output 2
as only position 1 and 3 matches. 这三个列表的比较将输出
2
因为只有位置1和3匹配。
I was thinking of converting it into tuple and then zipping it K=zip(A,B,C)
, then add each tuple to see if it matches the number of list. 我正在考虑将其转换为元组,然后将其压缩为
K=zip(A,B,C)
,然后添加每个元组以查看它是否与列表的数量匹配。
The problem almost sounds like I am missing something that is rather trivial, maybe! 问题几乎听起来像我错过了一些相当微不足道的东西,也许!
sum(1 if x == y == z else 0 for x, y, z in zip(A, B, C))
2
>>> A = [1, 0, 1, 1]
>>> B = [1, 1, 1, 1]
>>> C = [1, 0, 1, 0]
>>> [len(set(i)) == 1 for i in zip(A,B,C)]
[True, False, True, False]
>>> sum(len(set(i))==1 for i in zip(A,B,C))
2
Using set
, as in gnibbler's answer, works for lists containing any kinds of immutable elements -- arbitrary integers, floats, strings, tuples. 使用
set
,就像在gnibbler的答案中一样,适用于包含任何类型的不可变元素的列表 - 任意整数,浮点数,字符串,元组。 OP's question doesn't impose any restrictions on what the lists may contain, and assuming only 0 and 1 doesn't simplify anything. OP的问题并没有对列表可能包含的内容施加任何限制,并假设只有0和1不会简化任何事情。 The following also works for an arbitrary number of lists, not just 3, which does seem to be part of OP's requirements.
下面的方式也适用于列表任意数量的,不只是3,这似乎是的OP的要求的一部分。
A=[1,0,1,1, 'cat', 4.5, 'no']
B=[1,1,1,1, 'cat', False, 'no']
C=[1,0,1,0, 16, 'John', 'no']
D=[1,0,0,0, (4,3), 'Sally', 'no']
def number_of_matching_positions(*lists):
"""
Given lists, a list of lists whose members are all of the same length,
return the number of positions where all items in member lists are equal.
"""
return sum([len(set(t)) <= 1 for t in zip(* lists)])
print(number_of_matching_positions(),
number_of_matching_positions(A),
number_of_matching_positions(A, A),
number_of_matching_positions(A, B),
number_of_matching_positions(A, B, C),
number_of_matching_positions(A, B, C, D))
This will print 0 7 7 5 3 2
. 这将打印
0 7 7 5 3 2
。
If the number of lists N
can be large, performance can be improved by examining as few elements as possible of each tuple from the zip: 如果列表的数量
N
可以很大,则可以通过从zip中检查每个元组的尽可能少的元素来提高性能:
def all_equal(t):
"""Return True if all elements of the sequence t are equal, False otherwise."""
# Use a generator comprehension,
# so that 'all' will stop checking t[i] == t[0]
# as soon as it's false for some i.
return (not t) or \
all( (t[i] == t[0] for i in range(1, len(t))) )
def number_of_matching_positions_alt(*lists):
# Instead of 'len(set(t)) <= 1',
# do less work in case len(lists) alias len(t) can be large
return sum( [all_equal(t) for t in zip(* lists)] )
If you want to know the positions where all the lists are matching then 如果您想知道所有列表匹配的位置,那么
list(x for x, (xa, xb, xc) in enumerate(zip(a, b, c))
if xa == xb == xc)
seems to me the most readable way 在我看来,这是最可读的方式
If you want to just count the number of columns instead 如果您只想计算列数
sum(xa == xb == xc for xa, xb, xc in zip(a, b, c))
works thanks to the fact that in Python True
and False
can be used in computations as if they were 1
and 0
. 因为在Python中,
True
和False
可以在计算中使用,就好像它们是1
和0
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.