#python #string #list #find
Вопрос:
Дан абзац, представленный в виде списка слов:
context = ['Katie', 'Joplin', 'is', 'an', 'American', 'sitcom', 'created', 'by', 'Tom', 'Seeley', 'and', 'Norm', 'Gunzenhauser', '.', 'The', 'sitcom', 'received', 'positive', 'reviews', 'thanks', 'to', 'the', 'brilliance', 'of', 'Tom', 'Seeley', '.']
И список целевых строк из нескольких слов:
target = ['sitcom created', 'Tom Seeley']
Как получить индексы целевых объектов с несколькими словами?
В этом случае ответ должен быть:
[[5, 6], [8, 9], [24, 25]]
Ответ №1:
Если context
содержит только отдельные слова (без пробелов), вы можете объединить контекст в одну строку, а затем использовать str.index
:
target = ["sitcom created", "Tom Seeley"]
out, joined = [], " ".join(context)
for t in target:
try:
idx = joined.index(t)
cnt = joined[:idx].count(" ")
out.append([cnt, cnt t.count(" ")])
except:
continue
print(out)
С принтами:
[[5, 6], [8, 9]]
ИЗМЕНИТЬ: Для нескольких случаев:
target = ["sitcom created", "Tom Seeley"]
out, joined = [], " ".join(context)
for t in target:
idx = 0
while True:
try:
idx_new = joined[idx:].index(t)
cnt = joined[: idx idx_new].count(" ")
out.append([cnt, cnt t.count(" ")])
idx = idx_new len(t)
except:
break
print(out)
С принтами:
[[5, 6], [8, 9], [24, 25]]
Комментарии:
1. Это хорошо работает в данном контексте, но дает только первое вхождение. Если бы контекст повторил Том Сили, код должен получить все вхождения. Я изменил контекст, чтобы он содержал это.
Ответ №2:
Numpy выполняет операции на языке Си, так что это должен быть один из самых странных способов решения it….lol….as обычно мы используем его для численных вычислений, преобразуем массивы в numpy, а затем сравниваем их с помощью широковещания. Это предполагает, что цели из нескольких слов присутствуют в массиве
A = np.array(context)
B = np.array(['sitcom created'.split(), 'Tom Seeley'.split()])
np.argmax(A == B[..., None], axis=2)
# [[5, 6], [8, 9]]
y = np.where(A == B[..., None])
pre_x, pre_y=(None, None)
l = []
for x, y, z in np.vstack(y).T:
if x == pre_x and y == pre_y:
l[-1][-1].append(z)
elif x == pre_x and y != pre_y:
l[-1].append([z])
else:
l.append([[z]])
pre_x, pre_y = x, y
# [[[5, 15], [6]], [[8, 24], [9, 25]]]
from itertools import product
sum(map(list, map(lambda x: product(*x), l)), [])
# [(5, 6), (15, 6), (8, 9), (8, 25), (24, 9), (24, 25)]