我正在尝试编写一个函数来查看字符串列表并确定列表中的下一个字符串是否是前一个字符串的子字符串。
所以如果我有一份清单['Ryan', 'Rya', 'Ry', 'Testing', 'Test']
我会回来['Ryan', 'Rya', 'Ry', 'Test']
的。
我真的不知道从哪里开始。
您可以通过列表理解来完成此操作
def find_results(seq): #I'm sure you can name this function better
return [seq[0]] + [current for previous, current in zip(seq, seq[1:])
if current in previous]
seq[1:]
是除了第一个元素之外的整个列表
zip(a, b)
为您传递的每个可迭代对象生成成对的元素。在这种情况下,前面的字符串和当前字符串。
操作员将in
测试一个字符串是否在另一个字符串中。"test" in "testing"
是真的
理解说,对于每对字符串(当前和前一个),如果当前字符串是前一个字符串的子字符串,则构建所有当前字符串的列表
你可以这样做:
def f(lst):
yield lst[0]
for i in range(1, len(lst)):
prev_string = lst[i - 1]
curr_string = lst[i]
if curr_string in prev_string:
yield curr_string
f
将是一个生成器,因此要将其转换为列表,请将其传递给list
:
In [36]: f(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])
Out[36]: <generator object f at 0x02F75F08>
In [37]: list(f(['Ryan', 'Rya', 'Ry', 'Testing', 'Test']))
Out[37]: ['Ryan', 'Rya', 'Ry', 'Test']
你可以做:
l = ['Ryan', 'Rya', 'Ry', 'Testing', 'Test']
r = []
for i in range(1, len(l)):
if l[i] in l[i - 1]:
r.append(l[i])
或列表理解:
r = [l[i] for i in range(1,len(l)) if l[i] in l[i - 1]]
受Ryan Haining 的回答启发,我编写了一个基于生成器的版本,它适用于任何可迭代对象,而不仅仅是序列:
#!/usr/bin/env python2
from itertools import izip, tee
def find_results(iterable):
icur, iprev = tee(iterable)
yield next(icur)
for i in (cur for cur, prev in izip(icur, iprev) if cur in prev):
yield i
print list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test']))
Python 3 版本要短一些:
#!/usr/bin/env python3
from itertools import tee
def find_results(iterable):
icur, iprev = tee(iterable)
yield next(icur)
yield from (cur for cur, prev in zip(icur, iprev) if cur in prev)
print(list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])))
受到@CristianCiupitu 的启发,但我觉得他写它的方式令人困惑。这是它的简化版本。
>>> from itertools import izip, tee
>>> def find_results(iterable):
a, b = tee(iterable)
yield next(a)
for cur, prev in izip(a, b):
if cur in prev:
yield cur
>>> print(list(find_results(['Ryan', 'Rya', 'Ry', 'Testing', 'Test'])))
['Ryan', 'Rya', 'Ry', 'Test']