python - Python - 查找字符串列表中包含的唯一子字符串的索引,而无需遍历所有项目
问题描述
我有一个听起来像是已经问过的问题,但实际上我找不到一个真正好的答案。每天我都有一个包含几千个字符串的列表。我也知道这个字符串将始终包含一个包含“其他”一词的项目。例如,有一天我可能有:
a = ['mark','george', .... , " ...other ...", "matt','lisa', ... ]
改天我可能会得到:
a = ['karen','chris','lucas', ............................., '...other']
如您所见,包含子字符串“other”的项目的位置是随机的。我的目标是尽可能快地获得包含子字符串“其他”的项目的索引。我在这里找到了其他答案,大多数人建议对查找进行列表理解。例如:在 Python 中的列表中查找子字符串并检查 Python 列表项是否包含另一个字符串中的字符串 它们对我不起作用,因为它们太慢了。此外,其他解决方案建议使用“任何”来简单地检查列表中是否包含“其他”,但我需要索引而不是布尔值。我相信正则表达式可能是一个很好的潜在解决方案,即使我很难弄清楚如何。到目前为止,我只是设法做到了以下几点:
# any_other_value_available will tell me extremely quickly if 'other' is contained in list.
any_other_value_available = 'other' in str(list_unique_keys_in_dict).lower()
从这里开始,我不知道该怎么办。有什么建议么?谢谢
解决方案
探索的方法
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
推荐阅读
- ios - 是否可以在 AVFoundation 中创建自定义 flashMode?
- android - ARCore在PointCloud点的子集上获取/显示边界框?
- excel - 高效的 UDF 检查 Excel 中的公式一致性
- reactjs - React 形式的前导零
- google-bigquery - 当元素是BigQuery StandardSql中的对象时,我如何计算数组中的元素数
- selenium - 在 Selenium 中使用嵌套的 xpath 定位 webelement
- c++ - boost asio async_read() 似乎跳过了一些空值
- signalr.client - 使用 .Net 客户端连接时的 SignalR 404
- azure - 使用 azure cli 设置应用程序注册的 signInAudience
- sql - 如何在参数中使用sql