我如何检查列表是否在python中的数组中

时间:2018-10-29 15:02:51

标签: python python-3.x

例如,如果我有:

import numpy as np
A = np.array([[2,3,4],[5,6,7]])

,我想检查以下列表是否与数组组成的列表之一相同:

B = [2,3,4]

我尝试过

B in A #which returns True

但是以下内容也返回True,应该为false:

B = [2,2,2]
B in A

6 个答案:

答案 0 :(得分:6)

尝试使用此生成器理解。内置的any()短路,因此您不需要多余的评估。

any(np.array_equal(row, B) for row in A)

目前,np.array_equal尚未实现内部短路。在a different question中,讨论了完成此操作的不同方式对性能的影响。

正如@Dan在下面提到的那样,广播是解决此问题的另一种有效方法,通常(尽管并非总是)是一种更好的方法。对于一些粗略的启发式方法,这是您可能想在两种方法之间进行选择的方法。与其他任何微优化一样,对您的结果进行基准测试。

生成器理解

  • 减少内存占用(不创建阵列B==A
  • 短路(如果A的第一行是B,则我们不必查看其余行)
  • 当行很大时(定义取决于您的系统,但可能会在100到100,000之间),广播的速度并没有明显提高。
  • 使用内置语言功能。无论如何,您都已经安装了numpy,但是在没有理由不这样做的情况下,我倾向于使用核心语言。

广播

  • 使用numpy解决最广泛问题的最快方法。在这里使用它是一种好习惯。
  • 如果我们确实必须搜索A中的每一行(即,如果我们不经常希望B不在A中),广播将几乎总是更快(不一定总是快很多,请参阅下一点)
  • 当行很小时,生成器表达式将无法有效地向量化计算,因此广播将快要(除非您有足够多的行来短路,而忽略这些问题, )。
  • 在更广泛的上下文中,您拥有更多的numpy代码,此处使用广播可以帮助在代码库中使用更一致的模式。同事和未来,您将不将编码样式和样式混在一起。

答案 1 :(得分:3)

您可以通过使用以下广播来做到这一点:

import numpy as np
A = np.array([[2,3,4],[5,6,7]])
B = np.array([2,3,4]) # Or [2,3,4], a list will work fine here too

(B==A).all(axis=1).any()

答案 2 :(得分:1)

使用内置的any。一旦找到相同的元素,它将停止迭代并返回true。

import numpy as np

A = np.array([[2,3,4],[5,6,7]])
B = [3,2,4]

if any(np.array_equal(B, x) for x in A):
  print(f'{B} inside {A}')
else:
  print(f'{B} NOT inside {A}')

答案 3 :(得分:0)

您需要使用.all()来比较list的所有元素。

A = np.array([[2,3,4],[5,6,7]])
B = [2,3,4]

for i in A:
    if (i==B).all():
        print ("Yes, B is present in A")
        break

编辑:发现第一次出现时,我就把break打破了循环。这适用于诸如A = np.array([[2,3,4],[2,3,4]])

之类的示例
# print ("Yes, B is present in A")

使用any 的替代解决方案:

any((i==B).all() for i in A)

# True

答案 4 :(得分:0)

list((A[[i], :]==B).all() for i in range(A.shape[0])) 

[True, False]

这将告诉您A的哪一行等于B

答案 5 :(得分:0)

直接,您可以使用 any() 通过生成器将数组与 array_equal 进行比较。

from numpy import array_equal
import numpy as np

A = np.array([[2,3,4],[5,6,7]])
B = np.array([2,2,4]) 

in_A = lambda x, A : any((array_equal(a,x) for a in A))

print(in_A(B, A))
False

[Program finished]