Python 将字符串与列表匹配以迭代方式检索
有两个列表,一个由句子的字符序列组成,另一个由单词组成 目标是将第一个列表中的项目与第二个列表中的项目进行匹配,以确定li_a(len(li_a))时间的长度。相同的匹配词将临时保存为候选词。在最终的迭代过程之后,将选择最长的单词作为我们的预期结果,并将其添加到新列表中 由于Python 将字符串与列表匹配以迭代方式检索,python,list,Python,List,有两个列表,一个由句子的字符序列组成,另一个由单词组成 目标是将第一个列表中的项目与第二个列表中的项目进行匹配,以确定li_a(len(li_a))时间的长度。相同的匹配词将临时保存为候选词。在最终的迭代过程之后,将选择最长的单词作为我们的预期结果,并将其添加到新列表中 由于li_a中有18个字符,因此假设读写时间为18个 li_a = ['T','h','o','m','a','s','h','a','d','a','h','a','r','d','t','i','m','e'] li_wor
li_a
中有18个字符,因此假设读写时间为18个
li_a = ['T','h','o','m','a','s','h','a','d','a','h','a','r','d','t','i','m','e']
li_words = ['a','The','Thomas','have','had','has','hard','hot','time','tea']
首先,将li_a
中的第一项与li_单词
匹配
1. 'T' => li_words || li_a[0] => li_words
2. 'Th' => li_words || li_a[0]+li_a[1] => li_words
3. 'Tho' => li_words || li_a[0]+li_a[1]+li_a[2] => li_words
...
6. 'Thomas' => li_words || li_a[0]+..+li_a[5] => li_words (marks as candidate when the match is found)
...
18. 'Thomashadahardtime' => li_words || li_a[0]..li_a[17] => li_words
上面的例子显示了第一个迭代过程应该如何完成。它给了我们一个候选结果,那就是Thomas
。但是,从第一个'T'到's'(托马斯)的li_a
项将被扣除
li_a = ['h','a','d','a','h','a','r','d','t','i','m','e']
第二个迭代过程和前一个一样,应该被执行来检索下一个单词
最后,列表的最终结果应如下所示:
final_li = ['Thomas','had','a','hard','time']
尝试
下面的尝试适用于查找最长匹配,但不适用于迭代工作,并且在li\u words
def matched_substring(li1, li2):
new_li = []
tmp = ''
for a in li1:
tmp += a
count = 0
for b in li2:
if tmp == b:
count += 1
if count == 0:
tmp1 = tmp.replace(a, '')
new_li.append(tmp1)
tmp = a
if li2.__contains__(tmp):
new_li.append(tmp)
return new_li
它返回为:['Thomas','h','a','d','a','h','a','r','d','t','i','m']
UNICODE中的字符
string_a=“[]ဒီ|စစ်|ဆေး|မှု|ကို|သီး|ခြား|လွတ်|လပ်|တဲ့|ပု|ဂ္ဂို|လ်|တ|ဦး|က|ဦး|ဆောင်|ခိုင်း|တာ|ဟာ|လူ|ထု|အ|ကျိုး|အ|တွက်|ဖြစ်|တယ်|လို့|တ|ရား|ရေး|ဝန်|ကြီး|ဌာ|န|က|ထုတ်|ပြန်|တဲ့|ကြေ|ညာ|ချက်|ထဲ|မှာ|ဖေါ်|ပြ|ထား|ပါ|တယ်']"代码>
要将上述字符串转换为列表,请执行以下操作:
##Get rid of brackets & punctuation marks
strp_str = string_a.strip("[]")
strp_str = strp_str.strip("'")
##Now we achieve *li_a*
li_a = strp_str.split('|')
链接到剪贴板的li_单词
列表:
这里有一个使用itertools
的函数方法:
import itertools
li_a = ['T','h','o','m','a','s','h','a','d','a','h','a','r','d','t','i','m','e']
li_words = ['a','The','Thomas','have','had','has','hard','hot','time','tea']
res = list(itertools.imap(lambda x: max(itertools.ifilter(lambda y: x in y, li_words), key=len), li_a))
res
['Thomas', 'Thomas', 'Thomas', 'Thomas', 'Thomas', 'Thomas', 'Thomas', 'Thomas', 'hard', 'Thomas', 'Thomas', 'Thomas', 'hard', 'hard', 'time', 'time', 'Thomas', 'have']
其思想是,对于li_a
中的每个字母,我们过滤该字母中的li_单词,然后使用max
对该集合使用len
取最大的一个
下面是每个字母对应的拉链:
zip(li_a, res)
[('T', 'Thomas'), ('h', 'Thomas'), ('o', 'Thomas'), ('m', 'Thomas'), ('a', 'Thomas'), ('s', 'Thomas'), ('h', 'Thomas'), ('a', 'Thomas'), ('d', 'hard'), ('a', 'Thomas'), ('h', 'Thomas'), ('a', 'Thomas'), ('r', 'hard'), ('d', 'hard'), ('t', 'time'), ('i', 'time'), ('m', 'Thomas'), ('e', 'have')]
也许您可以尝试匹配由li_a
生成的字符串,例如
>>> li_a = ['T','h','o','m','a','s','h','a','d','a','h','a','r','d','t','i','m','e']
>>> li_words = ['a','The','Thomas','have','had','has','hard','hot','time','tea']
>>>
>>> s = "".join(li_a)
>>> for i in sorted(li_words,key=lambda x:-len(x)):
... if i in s:
... s=s.replace(i,str(li_words.index(i))+",")
...
>>> [li_words[int(i)] for i in s[:-1].split(",")]
['Thomas', 'had', 'a', 'hard', 'time']
希望这有帮助。以便获得所有可能的解决方案(以防还有一些“重叠”的词),可以首先为每个单词找到该特定单词可能出现的所有起始位置。然后,策略是从字符串的开头开始,测试所有可能出现在此处的候选词,并将字符串中相应数量的字符向前移动。在这个新位置,该过程将重复(由于递归,所有的组合都得到了探索)。一旦我们到达字符串的末尾,就找到了一个成功的解决方案
li_a = ['T', 'h','o','m','a','s','h','a','d','a','h','a','r','d','t','i','m','e','a']
li_words = ['a','The','Thomas','have','had','has','hard','hot','time','tea','timea']
def analyze(li_a, li_words):
s = ''.join(li_a)
#for each word, find all its positions in s
stat = {}
for word in li_words:
pos = s.find(word)
while pos != -1:
if not pos in stat:
stat[pos] = []
stat[pos].append(word)
pos = s.find(word, pos + 1)
solutions = []
def check(idx, solution):
if idx == len(s):
solutions.append(solution)
return
#at position idx, test all candidates and call
#itself recursively
words = stat.get(idx, [])
for word in words:
check(idx + len(word), solution + [word])
#start at the beginning
check(0, [])
return solutions
print(analyze(li_a, li_words))
编辑:
我测试了您的Unicode输入,似乎string\u a
包含一个单词ဖေါ်
在mm words.txt
中缺失。另一方面,在这种情况下,建议的解决方案无论如何都会失败。首先,在pos=s.find(word,pos+len(word))
中有一个错误,应该是pos=s.find(word,pos+1)
以查找特定单词的所有重叠出现。更重要的是,令人厌恶的复杂性要求(基本上是指数级的)使其无法在如此大的输入上使用。方法是采用。在下面的示例中,我仅从字符串a
中提取前10个单词(保存到str.txt
)为了避免丢失的一个:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def read_data(fname, delim, uniq = False):
with open(fname, 'r') as F:
data = F.read().split(delim)
data = map(lambda s: s.decode('utf-8').strip(), data)
data = filter(lambda s: s, data)
if uniq:
data = list(set(data))
return data
li_a = read_data('str.txt', '|')
li_words = read_data('mm-words.txt', '\n', uniq = True)
def analyze(li_a, li_words):
words = set(li_words)
s = ''.join(li_a[0:10])
N = len(s)
solutions = [ [] for idx in range(0, N) ]
S = [False for idx in range(0, N)]
for i in range(0, N):
flag = False
if (s[0:i+1] in words):
flag = True
solutions[i].append([s[0:i+1], -1])
else:
for j in range(1, i+1):
if S[j-1] and (s[j:i+1] in words):
#save the newly identified word and reference to solution
#previously found at location j-1
solutions[i].append([s[j:i+1], j-1])
#break #find only one solution
flag = True
S[i] = flag
splittings = []
def assemble(pos, L):
if pos == -1:
splittings.append(L)
return
for w,idx in solutions[pos]:
assemble(idx, [w] + L)
assemble(N-1, [])
return splittings
splittings = analyze(li_a, li_words)
for splitting in splittings:
print(' | '.join(splitting).encode('utf-8'))
这将产生:
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့
由于这个问题有等价的子问题,这是一个探索递归或动态编程方法的好机会。我认为在li_words
中执行循环项和在li_a
中匹配项会很容易,感谢您的快速响应,但是有一个错误声明为ValueError:invalid literal for int()以10为基数:
我的代码运行良好,当您使用int(i)
时,请确保i
不是空字符串。我尝试过您的代码。它对英文字母表运行良好,但它显示ValueError:invalid literal for int()以10为基数:
用于unicode字符。我已经尝试了该代码,它的效果非常好,但当我尝试使用unicode字符时,它返回空列表。对这种情况有何建议?谢谢您的出色工作。我的荣幸:)我想您正在使用Python2?您能发布产生空输出的特定li_a
/li_单词吗?这很可能与在这种情况下如何解释len
有关(即字节数与字符数)…谢谢你的支持。我用UNICODE字符扩展了帖子的细节。提前谢谢:)@htetmyet我已经更新了答案以处理测试数据,原来的方法太慢了,所以需要采取稍微不同的策略…@htetmyet是的,我想避免ဖေါ်
不会出现在您发布的单词列表中(因此在这种情况下,它找不到解决方案)
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ်လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ်လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွတ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီးခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ်ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စစ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့
ဒီ | စ | စ် | ဆေး | မှု | ကို | သီး | ခြား | လွ | တ် | လ | ပ် | တဲ့