检查Python中的列表中是否存在某些内容

我在Python中有一个元组列表,我有一个条件,如果元组不在列表中,我想取分支ONLY(如果它在列表中,那么我不想取if分支)

if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:


# Do Something

但这对我来说并不管用。我做错了什么?

1817215 次浏览

这个bug可能在代码中的其他地方,因为它应该可以正常工作:

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

或者使用元组:

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True

在Python中,我如何检查某些东西是否在列表中?

最便宜和最易读的解决方案是使用in操作符(或在您的特定情况下,not in)。正如文档中提到的,

操作符innot in测试成员关系。x in s的值为 如果xs的成员,则为True,否则为Falsex not in s回报 x in s的否定。

此外,

操作符not in被定义为具有in的逆真值。

y not in x在逻辑上与not y in x相同。

下面是一些例子:

'a' in [1, 2, 3]
# False


'c' in ['a', 'b', 'c']
# True


'a' not in [1, 2, 3]
# True


'c' not in ['a', 'b', 'c']
# False

这也适用于元组,因为元组是可哈希的(因为它们也是不可变的):

(1, 2) in [(3, 4), (1, 2)]
#  True

如果RHS上的对象定义了__contains__()方法,in将在内部调用它,正如文档中比较部分的最后一段所述。

< p >…innot in, 可迭代的类型或实现 __contains__()方法。例如,你可以(但不应该)这样做:

[3, 2, 1].__contains__(1)
# True

in会短路,所以如果你的元素在列表的开头,in会更快地求值:

lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst  # Expected to take longer time.


68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

如果你想做的不仅仅是检查一个项目是否在列表中,有以下选项:

  • list.index可用于检索项的索引。如果该元素不存在,将引发ValueError
  • list.count可以用来计数出现的次数。

XY问题:你考虑过__abc吗?

问自己这些问题:

  • 是否需要检查一个项目是否不止一次出现在列表中?
  • 这个检查是在循环中完成的,还是在重复调用的函数中完成的?
  • 列表中存储的项目是可哈希的吗?低,你可以调用hash对他们吗?

如果你对这些问题的回答是“是”,你应该使用set来代替。__abc2上的in隶属度测试是O(n)时间复杂度。这意味着python必须对列表进行线性扫描,访问每个元素并将其与搜索项进行比较。如果重复执行此操作,或者列表很大,则此操作将产生开销。

另一方面,set对象将散列它们的值以进行常数时间成员资格检查。检查也是使用in完成的:

1 in {1, 2, 3}
# True


'a' not in {'a', 'b', 'c'}
# False


(1, 2) in {('a', 'c'), (1, 2)}
# True

如果你很不幸,你正在搜索/不搜索的元素位于列表的末尾,python将扫描列表的末尾。从下面的时间安排可以明显看出这一点:

l = list(range(100001))
s = set(l)


%timeit 100000 in l
%timeit 100000 in s


2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

提醒一下,只要存储和查找的元素是可哈希的,这就是一个合适的选项。低,它们要么必须是不可变类型,要么必须是实现__hash__的对象。

你也可以使用list类的方法: 我们有一个列表:

x = [10,20,30,40,50]

确认我们是否有一个元素(i。e 10) 是否在列表中及其出现的频率:

if x.count(10):
print(x.count(10))
else:
print(10," Not in the list")

我知道这是一个非常古老的问题,但在OP的实际问题“我做错了什么?”中,问题似乎在于如何编码:

如果元组不在列表中,则只取分支

这在逻辑上等价于(正如OP所观察到的)

IF tuple in list THEN don't take the branch

然而,它对应该发生什么IF tuple not in list完全沉默。特别地,它紧随其后

IF tuple not in list THEN take the branch

所以OP的规则从来没有提到IF tuple not in list做什么。除此之外,正如其他答案所指出的,not in是检查对象是否在列表(或任何容器)中的正确语法。

my_tuple not in my_list # etc.