簡體   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