繁体   English   中英

检查 Python 的列表中是否有某些东西

[英]Check if something is (not) in a list in Python

我在Python中有一个元组列表,并且我有一个条件,只有当元组不在列表中时,我才想采用分支(如果它在列表中,那么我不想采用 if 分支)

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

    # Do Something

不过,这对我来说并不适用。 我做错了什么?

该错误可能在您的代码中的其他地方,因为它应该可以正常工作:

>>> 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参加成员资格测试的操作员。 如果xs的成员,则x in s计算结果为True ,否则为False x 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 上的 object 定义了一个__contains__()方法,则会in内部调用它,如文档比较部分的最后一段所述。

... 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 问题:你考虑过set s 吗?

问自己这些问题:

  • 您是否需要多次检查一个项目是否在列表中?
  • 这个检查是在循环内完成的,还是重复调用的 function?
  • 您存储在列表中的项目是否可散列? IOW,你能打电话给他们hash吗?

如果您对这些问题的回答是“是”,那么您应该改用set list s in成员资格测试是 O(n) 时间复杂度。 这意味着 python 必须对列表进行线性扫描,访问每个元素并将其与搜索项进行比较。 如果您重复执行此操作,或者列表很大,则此操作将产生开销。

另一方面, set对象 hash 它们的值用于恒定时间成员资格检查。 检查也使用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)

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

也可以使用列表 class 的计数方法:假设我们有一个列表:

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

要确认我们是否在列表中有一个元素(即 10)或 Not以及它的出现频率:

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是检查 object 是否在列表中(或任何容器中)的正确语法。

my_tuple not in my_list # etc.

暂无
暂无

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

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