2 回答

TA貢獻1828條經(jīng)驗 獲得超6個贊
探索的方法
1. 生成器方法
next(i for i,v in enumerate(test_strings) if 'other' in v)
2. 列表理解法
[i for i,v in enumerate(test_strings) if 'other' in v]
3. 將索引與生成器一起使用(由@HeapOverflow建議)
test_strings.index(next(v for v in test_strings if 'other' in v))
4. 帶生成器的正則表達式
re_pattern = re.compile('.*other.*')next(test_strings.index(x) for x in test_strings if re_pattern.search(x))
結論
索引方法具有最快的時間(@HeapOverflow在注釋中建議的方法)。
測試代碼
使用使用timeit的Perfplot
import random
import string
import re
import perfplot
def random_string(N):
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))
def create_strings(length):
M = length // 2
random_strings = [random_string(5) for _ in range(length)]
front = ['...other...'] + random_strings
middle = random_strings[:M] + ['...other...'] + random_strings[M:]
end_ = random_strings + ['...other...']
return front, middle, end_
def search_list_comprehension(test_strings):
return [i for i,v in enumerate(test_strings) if 'other' in v][0]
def search_genearator(test_strings):
return next(i for i,v in enumerate(test_strings) if 'other' in v)
def search_index(test_strings):
return test_strings.index(next(v for v in test_strings if 'other' in v))
def search_regex(test_strings):
re_pattern = re.compile('.*other.*')
return next(test_strings.index(x) for x in test_strings if re_pattern.search(x))
# Each benchmark is run with the '..other...' placed in the front, middle and end of a random list of strings.
out = perfplot.bench(
setup=lambda n: create_strings(n), # create front, middle, end strings of length n
kernels=[
lambda a: [search_list_comprehension(x) for x in a],
lambda a: [search_genearator(x) for x in a],
lambda a: [search_index(x) for x in a],
lambda a: [search_regex(x) for x in a],
],
labels=["list_comp", "generator", "index", "regex"],
n_range=[2 ** k for k in range(15)],
xlabel="lenght list",
# More optional arguments with their default values:
# title=None,
# logx="auto", # set to True or False to force scaling
# logy="auto",
# equality_check=numpy.allclose, # set to None to disable "correctness" assertion
# automatic_order=True,
# colors=None,
# target_time_per_measurement=1.0,
# time_unit="s", # set to one of ("auto", "s", "ms", "us", or "ns") to force plot units
# relative_to=1, # plot the timings relative to one of the measurements
# flops=lambda n: 3*n, # FLOPS plots
)
out.show()
print(out)
結果
length list regex list_comp generator index
1.0 10199.0 3699.0 4199.0 3899.0
2.0 11399.0 3899.0 4300.0 4199.0
4.0 13099.0 4300.0 4599.0 4300.0
8.0 16300.0 5299.0 5099.0 4800.0
16.0 22399.0 7199.0 5999.0 5699.0
32.0 34900.0 10799.0 7799.0 7499.0
64.0 59300.0 18599.0 11799.0 11200.0
128.0 108599.0 33899.0 19299.0 18500.0
256.0 205899.0 64699.0 34699.0 33099.0
512.0 403000.0 138199.0 69099.0 62499.0
1024.0 798900.0 285600.0 142599.0 120900.0
2048.0 1599999.0 582999.0 288699.0 239299.0
4096.0 3191899.0 1179200.0 583599.0 478899.0
8192.0 6332699.0 2356400.0 1176399.0 953500.0
16384.0 12779600.0 4731100.0 2339099.0 1897100.0

TA貢獻1890條經(jīng)驗 獲得超9個贊
如果你正在尋找一個子字符串,正則表達式是找到它的好方法。
在你的情況下,你正在尋找所有包含“other”的子字符串。正如您已經(jīng)提到的,列表中的元素沒有特殊順序。因此,對所需元素的搜索是線性的,即使它是有序的。
可能描述您的搜索的正則表達式是 。關于文檔query='.*other.*'
.(點。在默認模式下,這將匹配除換行符以外的任何字符。如果已指定 DOTALL 標志,則此標志將匹配任何字符,包括換行符。
*使生成的 RE 與前一個 RE 的 0 次或更多次重復匹配,并盡可能多地重復。ab* 將匹配 “a”、“ab”或 “a”,后跟任意數(shù)量的 “b”。
在之前和之后,任何字符都可以有0個或更多次重復。.*other
例如
import re
list_of_variables = ['rossum', 'python', '..other..', 'random']
query = '.*other.*'
indices = [list_of_variables.index(x) for x in list_of_variables if re.search(query, x)]
這將返回包含 .在此示例中,將是 ,因為 是列表中的第三個元素。queryindices[2]'...other...'
- 2 回答
- 0 關注
- 156 瀏覽
添加回答
舉報