简体   繁体   English

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

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

I have a list of tuples in Python , and I have a conditional where I want to take the branch ONLY if the tuple is not in the list (if it is in the list, then I don't want to take the if branch)我在Python中有一个元组列表,并且我有一个条件,只有当元组不在列表中时,我才想采用分支(如果它在列表中,那么我不想采用 if 分支)

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

    # Do Something

This is not really working for me though.不过,这对我来说并不适用。 What have I done wrong?我做错了什么?

The bug is probably somewhere else in your code, because it should work fine:该错误可能在您的代码中的其他地方,因为它应该可以正常工作:

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

Or with tuples:或者使用元组:

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

How do I check if something is (not) in a list in Python?如何检查 Python 中的列表中是否有某些内容?

The cheapest and most readable solution is using the in operator (or in your specific case, not in ).最便宜和最易读的解决方案是使用in运算符(或在您的特定情况下, not in )。 As mentioned in the documentation,如文档中所述,

The operators in and not in test for membership. innot in参加成员资格测试的操作员。 x in s evaluates to True if x is a member of s , and False otherwise.如果xs的成员,则x in s计算结果为True ,否则为False x not in s returns the negation of x in s . x not in s返回x in s的否定。

Additionally,此外,

The operator not in is defined to have the inverse true value of in .运算符not in被定义为具有in的反真值。

y not in x is logically the same as not y in x . y not in x在逻辑上与not y in x相同。

Here are a few examples:这里有一些例子:

'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

This also works with tuples, since tuples are hashable (as a consequence of the fact that they are also immutable):这也适用于元组,因为元组是可散列的(因为它们也是不可变的):

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

If the object on the RHS defines a __contains__() method, in will internally call it, as noted in the last paragraph of the Comparisons section of the docs.如果 RHS 上的 object 定义了一个__contains__()方法,则会in内部调用它,如文档比较部分的最后一段所述。

... in and not in , are supported by types that are iterable or implement the __contains__() method. ... innot in由可迭代或实现__contains__()方法的类型支持。 For example, you could (but shouldn't) do this:例如,您可以(但不应该)这样做:

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

in short-circuits, so if your element is at the start of the list, in evaluates faster: 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)

If you want to do more than just check whether an item is in a list, there are options:如果您想做的不仅仅是检查项目是否在列表中,还有以下选项:

  • list.index can be used to retrieve the index of an item. list.index可用于检索项目的索引。 If that element does not exist, a ValueError is raised.如果该元素不存在,则会引发ValueError
  • list.count can be used if you want to count the occurrences.如果要计算出现次数,可以使用list.count

The XY Problem: Have you considered set s? XY 问题:你考虑过set s 吗?

Ask yourself these questions:问自己这些问题:

  • do you need to check whether an item is in a list more than once?您是否需要多次检查一个项目是否在列表中?
  • Is this check done inside a loop, or a function called repeatedly?这个检查是在循环内完成的,还是重复调用的 function?
  • Are the items you're storing on your list hashable?您存储在列表中的项目是否可散列? IOW, can you call hash on them? IOW,你能打电话给他们hash吗?

If you answered "yes" to these questions, you should be using a set instead.如果您对这些问题的回答是“是”,那么您应该改用set An in membership test on list s is O(n) time complexity.list s in成员资格测试是 O(n) 时间复杂度。 This means that python has to do a linear scan of your list, visiting each element and comparing it against the search item.这意味着 python 必须对列表进行线性扫描,访问每个元素并将其与搜索项进行比较。 If you're doing this repeatedly, or if the lists are large, this operation will incur an overhead.如果您重复执行此操作,或者列表很大,则此操作将产生开销。

set objects, on the other hand, hash their values for constant time membership check.另一方面, set对象 hash 它们的值用于恒定时间成员资格检查。 The check is also done using in :检查也使用in完成:

1 in {1, 2, 3} 
# True

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

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

If you're unfortunate enough that the element you're searching/not searching for is at the end of your list, python will have scanned the list upto the end.如果您很不幸,您正在搜索/未搜索的元素位于列表的末尾,python 将扫描列表直到最后。 This is evident from the timings below:从下面的时间可以看出这一点:

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)

As a reminder, this is a suitable option as long as the elements you're storing and looking up are hashable.提醒一下,只要您存储和查找的元素是可散列的,这是一个合适的选项。 IOW, they would either have to be immutable types, or objects that implement __hash__ . IOW,它们要么必须是不可变类型,要么必须是实现__hash__的对象。

One can also use the count method of list class: lets say we have a list:也可以使用列表 class 的计数方法:假设我们有一个列表:

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

To confirm if we have an element(ie 10) in the list or Not and the frequency of its occurrence:要确认我们是否在列表中有一个元素(即 10)或 Not以及它的出现频率:

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

I know this is a very old question but in the OP's actual question of "What have I done wrong?", the problem seems to be in how to code:我知道这是一个非常古老的问题,但在 OP 的“我做错了什么?”的实际问题中,问题似乎在于如何编码:

take the branch ONLY if the tuple is not in the list仅当元组不在列表中时才使用分支

This is logically equivalent to (as OP observes)这在逻辑上等同于(正如 OP 所观察到的)

IF tuple in list THEN don't take the branch

It's, however, entirely silent on what should happen IF tuple not in list .但是, IF tuple not in list应该发生什么,它完全保持沉默。 In particular, it doesn't follow that特别是,它遵循

IF tuple not in list THEN take the branch

So OP's rule never mentions what to do IF tuple not in list .所以 OP 的规则从来没有提到IF tuple not in list该怎么做。 Apart from that, as the other answers have noted, not in is the correct syntax to check if an object is in a list (or any container really).除此之外,正如其他答案所指出的, not in是检查 object 是否在列表中(或任何容器中)的正确语法。

my_tuple not in my_list # etc.

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

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