![](/img/trans.png)
[英]Python - Fastest way to check if a string contains specific characters in any of the items in a list
[英]Fastest way to check if a string can be created with a list of characters in python
我需要檢查是否可以使用字符列表創建字符串並返回True或False。
我正在使用list.count或collections.Counter的不同解決方案。
我也在使用這個解決方案,我不需要通讀字符列表:
def check(message, characters):
try:
[list(characters).remove(m) for m in message]
return True
except:
return False
有最快的方式嗎? 對於一個非常非常大的角色列表。 計數器和列表計數似乎較慢。 不知道是否有快速的pythonic方式來做到這一點。
例:
message = "hello"
characters = "hheellooasdadsfgfdgfdhgfdlkgkfd"
check(message, characters) # this should return True or False
# characters can be a veeeeery long string
重復事項 ,例如characters =“hheloo”不適用於message =“hello”
您可以使用collections.Counter()
。 只需構建兩個計數器並使用subtract()
方法檢查是否有任何負數:
>>> c1 = Counter(characters)
>>> c2 = Counter(message)
>>> c1.subtract(c2)
>>> all(v >= 0 for v in c1.values())
False
這應該在線性時間內起作用。
這在線性時間內是不可行的,因為兩個字符串的長度都很重要,並且需要為每個字符迭代它們。 在沒有檢查其實際實現的情況下,我假設remove()
是對數的。
def check(msg, chars):
c = list(chars) # Creates a copy
try:
for m in msg:
c.remove(m)
except ValueError:
return False
return True
if __name__ == '__main__':
print(check('hello', 'ehlo'))
print(check('hello', 'ehlol'))
print(check('hello', 'ehloijin2oinscubnosinal'))
與eugene的解決方案和jbndlr的解決方案相比,這是另一種解決方案。
def test1(input_word, alphabet):
alp_set = set(list(alphabet))
in_set = set(list(input_word))
return in_set.issubset(alp_set)
def test2(input_word, alphabet):
c1 = collections.Counter(alphabet)
c2 = collections.Counter(input_word)
c1.subtract(c2)
return all(v >= 0 for v in c1.values())
def check(msg, chars):
c = list(chars) # Creates a copy
try:
for m in msg:
c.remove(m)
except ValueError:
return False
return True
input_word = "hello"
alphabet = "hheellooasdadsfgfdgfdhgfdlkgkfd"
start_time = time.time()
for i in range(10000):
test1(input_word,alphabet)
print("--- %s seconds ---" % (time.time() - start_time))
start_time = time.time()
for i in range(10000):
test2(input_word,alphabet)
print("--- %s seconds ---" % (time.time() - start_time))
start_time = time.time()
for i in range(10000):
check(input_word,alphabet)
print("--- %s seconds ---" % (time.time() - start_time))
>> --- 0.03100299835205078 seconds ---
>> --- 0.24402451515197754 seconds ---
>> --- 0.022002220153808594 seconds ---
⇒jbndlr的解決方案是最快的 - 對於這個測試用例。
另一個測試用例:
input_word = "hellohellohellohellohellohellohellohellohellohellohellohellohello"
alphabet =
“”
>> --- 0.21964788436889648 seconds ---
>> --- 0.518169641494751 seconds ---
>> --- 1.3148927688598633 seconds ---
⇒test1是最快的
有一種更快的方法可以做到這一點,顯然是由於創建all()生成器的成本( 為什么Python的'all'函數如此慢? )也許for循環更快,擴展@eugene y的答案:
from collections import Counter
import time
message = "hello"
characters = "hheeooasdadsfgfdgfdhgfdlkgkfd"
def check1(message,characters):
c1 = Counter(characters)
c2 = Counter(message)
c1.subtract(c2)
return all(v > -1 for v in c1.values())
def check2(message,characters):
c1 = Counter(characters)
c2 = Counter(message)
c1.subtract(c2)
for v in c1.values():
if v < 0:
return False
return True
st = time.time()
for i in range(350000):
check1(message,characters)
end = time.time()
print ("all(): "+str(end-st))
st = time.time()
for i in range(350000):
check2(message,characters)
end = time.time()
print ("for loop: "+str(end-st))
結果:
all(): 5.201688051223755
for loop: 4.864434719085693
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.