簡體   English   中英

Python - 有效地檢查列表是否存在且元素是否存在於列表中

[英]Python - efficiently check a list exists AND element exists in list

我有一個變量foo ,它指向一個字符串"bar"

foo = "bar"

我有一個名為whitelist的列表。 如果whitelist不為空,則包含的元素是一個白名單。 如果whitelist為空,則 if 語句允許任何字符串。

我已經實現了如下

whitelist = ["bar", "baz", "x", "y"]

if whitelist and foo in whitelist:
    print("bar is whitelisted")
    # do something with whitelisted element

if whitelist ,據我了解,檢查whitelist是否返回True 如果白名單為空,白名單將為False 如果whitelist包含元素,它將返回True

但是,它的真正實現包含:

  • 很多字符串要檢查,例如“bar”、“baz”、“x”、“y”、“a”、“b”
  • 很多白名單要檢查

因此,我想知道是否有一種計算效率更高的方法來編寫 if 語句 每次檢查白名單是否存在似乎效率低下,可以簡化。

這些是檢查元素是否在列表中的一些方法。

from timeit import timeit
import numpy as np




whitelist1 = {"bar", "baz", "x", "y"}
whitelist2 = np.array(["bar", "baz", "x", "y"])

def func1():
    return {"foo"}.intersection(whitelist1)

def func2():
    return "foo" in whitelist1

def func3():
    return np.isin('foo',whitelist1)


def func4():
    return whitelist2[np.searchsorted(whitelist2, 'foo')] == 'foo'




print("func1=",timeit(func1,number=100000))
print("func2=",timeit(func2,number=100000))
print("func3",timeit(func3,number=100000))
print("func4=",timeit(func4,number=100000))

每個 function 所用時間

func1= 0.01365450001321733
func2= 0.005112499929964542
func3 0.5342871999600902
func4= 0.17057700001168996

FOR 隨機生成的列表

from timeit import timeit
import numpy as np
import random as rn
from string import ascii_letters


# randomLst = for a in range(500) rn.choices(ascii_letters,k=5)

randomLst = []
while len(randomLst) !=1000:
    radomWord = ''.join(rn.choices(ascii_letters,k=5))
    if radomWord not in randomLst:
        randomLst.append(radomWord)


whitelist1 = {*randomLst}
whitelist2 = np.array(randomLst)
randomWord = rn.choice(randomLst)
randomWords = set(rn.choices(randomLst, k=100))


def func1():
    return {randomWord}.intersection(whitelist1)

def func2():
    return randomWord in whitelist1

def func3():
    return np.isin('foo',whitelist1)


def func4():
    return whitelist2[np.searchsorted(whitelist2, randomWord)] == randomWord


def func5():
    return randomWords & whitelist1

print("func1=",timeit(func1,number=100000))
print("func2=",timeit(func2,number=100000))
print("func3",timeit(func3,number=100000))
print("func4=",timeit(func4,number=100000))
print("func5=",timeit(func5,number=1000)) # Here I change the number to 1000 because we check the 100 randoms word at one so number = 100000/100 = 1000.

用的時間

func1= 0.012835499946959317
func2= 0.005004600039683282
func3 0.5219665999757126
func4= 0.19900090002920479
func5= 0.0019264000002294779

結論

  1. 如果您只想檢查一個單詞,那么“in”語句很快

  2. 但是,如果你有一個單詞列表,那么 '&' 語句是快速的 'func5'

注意:function 5 返回一個包含白名單中的單詞的集合

whitelist會存在,但如果可能的話None強制:

whitelist = whitelist or []

如上所述,您只需foo in whitelist中即可確定它是否在列表中。 這是O(len(whitelist))操作。 Arrays 在實踐中速度驚人(例如,至少len(whitelist) >= 1,000 )。

如果您需要它更快地使用一個集合,並且如果您需要進行n查找,可以選擇將您的 foos 收集到一個集合中,然后使用 intersect for O(n)

foos = { 'bar', 'none' }
whitelist = { 'bar' }
for foo in foos & whitelist:
   print(foo)

這是簡化的解決方案,您可以使用兩種方法來做到這一點

whitelist = ["bar", "baz", "x", "y"]
foo = "bar"
# method 1
def WhiteListExists(foo, whitelist):
    if whitelist and foo in whitelist:
        return True
    else:
        return False

exists = WhiteListExists(foo,whitelist)

# method 2
exists = True if whitelist and foo in whitelist else False

兩種方法都一樣,但第二種方法很快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM