如何快速檢查 Python 列表中是否存在特定值
我們將介紹不同的方法來檢查 Python 列表中是否存在特定值並比較它們的效能。
這些方法包括
in
檢查 Python 列表中值是否存在的方法
in
是在 Python 列表、集合、字典或其他可迭代的 Python 物件中執行成員資格檢查的正確方法。
>>> testList = [1, 2, 3, 4]
>>> 2 in testList
True
>>> 6 in testList
False
在 Python 中將列表轉換為集合 set
,然後進行成員資格檢查
如果列表長度增加,則列表成員資格檢查可能效率不高,尤其是如果列表中存在重複元素。
在這種情況下,Python 集合 set
是進行成員資格檢查的更好的資料型別,因為集合中的元素值都是唯一的。
列表和集合成員資格檢查之間的效能比較
我們將比較四種情況下的效果差異,
- 原始列表具有唯一值,並且選中的值存在於列表中
- 原始列表具有唯一值,並且列表中不存在檢查的值
- 原始列表具有重複的值,並且檢查的值存在於列表中
- 原始列表只有重複的值,並且列表中不存在檢查的值
原始列表僅具有唯一值,並且選中的值存在於列表中
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = a[:n//2].tolist()
randomvalue = randomlist[len(randomlist)//2]
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return (y in x)
def inSetMethod(L):
x, y = L
x = set(x)
return (y in x)
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=['in list', 'in set'],
n_range=[2**k for k in range(1, 20)],
xlabel='Data Length',
title='unique values in list and to-be-checked value exists in the list',
logx=True,
logy=True)
原始列表只有唯一值,並且列表中不存在檢查的值
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = a[:n//2].tolist()
randomvalue = n+1
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return (y in x)
def inSetMethod(L):
x, y = L
x = set(x)
return (y in x)
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=['in list', 'in set'],
n_range=[2**k for k in range(1, 20)],
xlabel='Data Length',
title='unique values in list and to-be-checked value does not exist in the list',
logx=True,
logy=True)
原始列表具有重複的值,並且檢查的值存在於列表中
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = np.random.choice(n, n//2).tolist()
randomvalue = randomlist[len(randomlist)//2]
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return (y in x)
def inSetMethod(L):
x, y = L
x = set(x)
return (y in x)
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=['in list', 'in set'],
n_range=[2**k for k in range(2, 20)],
xlabel='Data Length',
title='duplicate values in list and to-be-checked value exists in the list',
logx=True,
logy=True)
原始列表只有重複的值,並且列表中不存在檢查的值
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = np.random.choice(n, n//2).tolist()
randomvalue = n+1
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return (y in x)
def inSetMethod(L):
x, y = L
x = set(x)
return (y in x)
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=['in list', 'in set'],
n_range=[2**k for k in range(2, 20)],
xlabel='Data Length',
title='duplicate values in list and to-be-checked value does not exist in the list',
logx=True,
logy=True)
效能效果比較結論
儘管 Python 中的 set
成員資格檢查比 Python 列表 list
中的成員資格檢查更快,但是從列表 list
進行轉換或集合 set
消耗時間。因此,如果給定的資料是 Python 列表,那麼如果你首先將列表轉換為 set
,然後執行 set
成員資格檢入,則不會帶來任何效能上的好處。
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
unique_randomlist = a[:n//2].tolist()
duplicate_randomlist = np.random.choice(n, n//2).tolist()
existing_randomvalue = unique_randomlist[len(unique_randomlist)//2]
nonexisting_randomvalue = n+1
return [unique_randomlist, duplicate_randomlist,
existing_randomvalue, nonexisting_randomvalue]
def inListMethod_UniqueValue_ValueExisting(L):
u, d, ex, ne = L
return (ex in u)
def inListMethod_DuplicateValue_ValueExisting(L):
u, d, ex, ne = L
return (ex in d)
def inListMethod_UniqueValue_ValueNotExisting(L):
u, d, ex, ne = L
return (ne in u)
def inListMethod_DuplicateValue_ValueNotExisting(L):
u, d, ex, ne = L
return (ne in d)
def inSetMethod_UniqueValue_ValueExisting(L):
u, d, ex, ne = L
u = set(u)
return (ex in u)
def inSetMethod_DuplicateValue_ValueExisting(L):
u, d, ex, ne = L
d = set(d)
return (ex in d)
def inSetMethod_UniqueValue_ValueNotExisting(L):
u, d, ex, ne = L
u = set(u)
return (ne in u)
def inSetMethod_DuplicateValue_ValueNotExisting(L):
u, d, ex, ne = L
d = set(d)
return (ne in d)
perfplot.show(
setup=setupTest,
equality_check=None,
kernels=[inListMethod_UniqueValue_ValueExisting,
inListMethod_DuplicateValue_ValueExisting,
inListMethod_UniqueValue_ValueNotExisting,
inListMethod_DuplicateValue_ValueNotExisting,
inSetMethod_UniqueValue_ValueExisting,
inSetMethod_DuplicateValue_ValueExisting,
inSetMethod_UniqueValue_ValueNotExisting,
inSetMethod_DuplicateValue_ValueNotExisting],
labels=[ 'inListMethod_UniqueValue_ValueExisting',
'inListMethod_DuplicateValue_ValueExisting',
'inListMethod_UniqueValue_ValueNotExisting',
'inListMethod_DuplicateValue_ValueNotExisting',
'inSetMethod_UniqueValue_ValueExisting',
'inSetMethod_DuplicateValue_ValueExisting',
'inSetMethod_UniqueValue_ValueNotExisting',
'inSetMethod_DuplicateValue_ValueNotExisting'],
n_range=[2**k for k in range(2, 20)],
xlabel='Data Length',
logx=True,
logy=True)
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn