我在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
How do I check if something is (not) in a list in Python?
最便宜和最易读的解决方案是使用in
运算符(或在您的特定情况下,not in
)。如文档中所述,
运营商
in
和not in
测试会员资格。如果x in s
是True
的成员,x
评估为s
,否则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上的对象定义了__contains__()
方法,in
将在内部调用它,如文档的Comparisons部分的最后一段所述。
...
in
和not 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
。set
s?问自己这些问题:
hash
吗?如果你对这些问题回答“是”,那么你应该使用set
代替。 in
s的list
成员资格测试是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)
提醒一下,只要您存储和查找的元素可以清洗,这是一个合适的选项。 IOW,它们要么必须是不可变类型,要么是实现__hash__
的对象。