简体   繁体   English

如何比较列表中的相应位置?

[英]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中, TrueFalse可以在计算中使用,就好像它们是10

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM