如何比较 python 中的两个列表

How to compare two lists in python

假设我有两个列表(或 numpy.arrays):

a = [1,2,3]
b = [4,5,6]

如何检查 a 的每个元素是否小于相同索引处 b 的对应元素? (我假设索引从 0 开始) 即

at index 0 value of a = 1 < value of b = 4
at index 1 value of a = 2 < value of b = 5
at index 2 value of a = 3 < value of b = 6

如果 a 等于 [1,2,7],那将是不正确的,因为在索引 2 处 a 的值大于 b 的值。此外,如果 a 的长度小于 b 的长度,它应该只比较 ab 的索引。

比如这对a,b

a = [1,2]
b = [3,4,5]

在索引 0 和 1 处,a 的值小于 b,因此这也将通过检查。

P.S.--> 我必须在 if 语句中使用上述条件。 而且,a 的任何元素都不应等于 b 的元素,即严格小于。随意使用尽可能多的工具。 (虽然我这里用的是列表,你也可以把上面的列表转成numpy数组。)

zipall

回答两个部分
all(i < j for (i, j) in zip(a, b))

zip 会将 a 开头的值与 b 开头的值配对;当较短的可迭代对象 运行 结束时,迭代结束。 all returns True 当且仅当给定的所有项目在布尔上下文中都为真。此外,当任何项目失败时,False 将提前返回。

示例结果:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> all(i < j for (i, j) in zip(a, b))
True
>>> a = [1,2,7]
>>> b = [4,5,6]
>>> all(i < j for (i, j) in zip(a, b))
False
>>> a = [1,2]
>>> b = [4,5,-10]
>>> all(i < j for (i, j) in zip(a, b))
True

时间 IPython 3.4.2:

In [1]: a = [1] * 10000
In [2]: b = [1] * 10000
In [3]: %timeit all(i < j for (i, j) in zip(a, b))
1000 loops, best of 3: 995 µs per loop
In [4]: %timeit all(starmap(lt, zip(a, b)))
1000 loops, best of 3: 487 µs per loop

所以星图在这种情况下更快。通常 Python 中有两件事相对较慢:函数调用和全局名称查找。 starmap 似乎在这里赢了,因为从 zip 产生的元组可以按原样作为 *args 提供给 lt 内置函数,而我的代码需要解构它。

作为变体,又快又短

from operator import lt
from itertools import starmap, izip
all(starmap(lt, izip(a, b)))

由于这个问题有一个 numpy 标签,我想我会提供一个 numpy 解决方案。

您只能在等长的 arrays 上使用 < 运算符,因此如果您的 arrays 长度不同,您需要缩短最长的一个。

In [26]: import numpy as np

In [27]: a = [1,2,3]

In [28]: b = [4,5,6]

In [29]: np.all(a < b)
Out[29]: True

In [30]: a = [1,2]

In [31]: b = [3,4,5]

In [32]: shortest = min(len(a), len(b))

In [33]: np.all(a[:shortest] < b[:shortest])
Out[33]: True

只是另一种方式,不确定它对其他答案的表现如何:

a = [1,2,3]
b = [4,5,6]
if filter(lambda x: x[0] < x[1], zip(a,b)):
    return True

我在 if 语句中使用它,因为问题表明它将像那样使用,并且那里不需要 bool 转换。否则我会将 filter() 包装在 bool() 中。 同样,这只是为了演示一种替代方法,并不意味着成为最有效的方法。