Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 试图找到一种聪明的方法来查找给定字符串中关键字的索引_Python - Fatal编程技术网

Python 试图找到一种聪明的方法来查找给定字符串中关键字的索引

Python 试图找到一种聪明的方法来查找给定字符串中关键字的索引,python,Python,我知道有很多关于在字符串中查找给定关键字的索引的主题,但我的情况有点不同 我有两个输入,一个是字符串,另一个是映射列表(或者随便你怎么称呼它) 每个单词将始终映射到映射列表中的一个数字上。现在我想在匹配字符串时找到给定数字的所有索引,比如1 在上述情况下,它将返回[0,2,17](Thakns@rahlf23) 我目前的方法是通过执行以下操作将每个单词压缩成一个数字 zip(mapping_list.split(' '), s.split(' ')) 这让我 ('1', 'I') ('1',

我知道有很多关于在字符串中查找给定关键字的索引的主题,但我的情况有点不同

我有两个输入,一个是字符串,另一个是映射列表(或者随便你怎么称呼它)

每个单词将始终映射到映射列表中的一个数字上。现在我想在匹配字符串时找到给定数字的所有索引,比如1

在上述情况下,它将返回[0,2,17](Thakns@rahlf23)

我目前的方法是通过执行以下操作将每个单词压缩成一个数字

zip(mapping_list.split(' '), s.split(' '))
这让我

('1', 'I')
('1', 'am')
('2', 'awesome')
('3', 'and')
('1', 'I')
('2', 'love')
('3', 'you')
然后遍历列表,找到“1”,使用这个词生成一个正则表达式,然后搜索索引并将其附加到列表或其他内容中。冲洗并重复

然而,这似乎非常低效,尤其是当
s
变得非常长时


我想知道是否有更好的方法来处理这个问题。

你可以
将这些单词映射到它们的
len
并使用,尽管你必须在每个长度(空格)中添加
1
,并在第一个单词的开头添加一个首字母
0

>>> words = "I am awesome and I love you".split()
>>> mapping = list(map(int, "1 1 2 3 1 2 3".split()))
>>> start_indices = list(itertools.accumulate([0] + [len(w)+1 for w in words]))
>>> start_indices
[0, 2, 5, 13, 17, 19, 24, 28]
最后一个元素未使用。然后,
zip
并迭代这些对,并将它们收集到字典中

>>> d = collections.defaultdict(list)
>>> for x, y in zip(mapping, start_indices):
...     d[x].append(y)
>>> dict(d)
>>> {1: [0, 2, 17], 2: [5, 19], 3: [13, 24]}
或者,您也可以使用like
\b\w
(单词边界后跟单词字符)来查找单词开始的每个位置,然后按照上述步骤进行操作

>>> s = "I am awesome and I love you"
>>> [m.start() for m in re.finditer(r"\b\w", s)]
[0, 2, 5, 13, 17, 19, 24]

你这么做过很多次吗?或者你只是担心
s
变长?这可能接近最优,我看到的唯一改进是将
s.split
转换为一个用于恒定内存的生成器。不过,我有点怀疑这是一个瓶颈。我认为它应该返回
[0,2,17]
。或者使用默认值dict@JChao您是否尝试使用很长的字符串来计时您的解决方案?假设将有1k个
s
,并且在
拆分后,每个
s
将有50到100个字符长,列表的典型长度是7到10谢谢!这些方法看起来比我的干净多了。不过我要做一些快速基准测试。
>>> s = "I am awesome and I love you"
>>> [m.start() for m in re.finditer(r"\b\w", s)]
[0, 2, 5, 13, 17, 19, 24]
# Find the indices of all the word starts
word_starts = [0] + [m.start()+1 for m in re.finditer(' ', s)]

# Break the mapping list into an actual list
mapping = mapping_list.split(' ')

# Find the indices in the mapping list we care about
word_indices = [i for i, e in enumerate(mapping) if e == '1']

# Map those indices onto the word start indices
word_starts_at_indices = [word_starts[i] for i in word_indices]
# Or you can do the last line the fancy way:
# word_starts_at_indices = operator.itemgetter(*word_indices)(word_starts)