3

检查数组/元组/列表是否仅包含另一个数组/元组/列表中的元素的最佳方法是什么?

我尝试了以下两种方法,对于不同类型的集合,哪种方法更好/更 Pythonic?我可以使用哪些其他(更好的)方法进行此检查?

import numpy as np

input = np.array([0, 1, -1, 0, 1, 0, 0, 1])
bits = np.array([0, 1, -1])

# Using numpy
a=np.concatenate([np.where(input==bit)[0] for bit in bits])
if len(a)==len(input):
    print 'Valid input'

# Using sets
if not set(input)-set(bits):
    print 'Valid input'
4

3 回答 3

5

由于您已经在使用 numpy 数组,因此可以使用in1d函数:

>>> import numpy as np
>>> 
>>> input = np.array([0, 1, -1, 0, 1, 0, 0, 1])
>>> bits = np.array([0, 1, -1])
>>> 
>>> if np.in1d(input, bits).all():
...     print 'Valid input'
... 
Valid input
于 2012-05-09T18:02:45.797 回答
4

对于大型集合,您# Using numpy的效率非常低,因为它会创建输入列表的完整副本。

我可能会这样做:

if all(i in bits for i in input):
    print 'Valid input'

这是一种非常pythonic的方式来编写你想要做的事情,它的好处是它不会创建一个可能很大的整个list(或),它会在第一次遇到时停止(并返回)中的一个元素不在.setFalseinputbits

于 2012-05-09T17:58:46.527 回答
2

通常你会以这种方式使用 set,它可能比使用 operator - 重新计算新集合更快:

input = set([0, 1, -1, 0, 1, 0, 0, 1])
bits = set([0, 1, -1])

input.issubset(bits)

编辑:

issubset 正是针对这个问题编写的方法(参见http://hg.python.org/releasing/2.7.3/file/7bb96963d067/Objects/setobject.c的源代码)。它基本上等同于:

def issubset(self, other):
    if len(self) > len(other):
        return False

    for i in self:
        if i not in other:
            return False

    return True
于 2012-05-09T18:07:32.877 回答