我正在研究一个函数,给定一个序列,尝试在列表中找到所述序列,然后应该在该序列终止后立即返回列表项。
目前这段代码确实在序列结束后立即返回列表项,但是我不满足于拥有这么多嵌套的if语句并且很想重写它但是我不知道该如何去关于它,因为它与我过去写过的任何东西完全不同,并且感觉有点不合时宜。
def sequence_in_list(seq, lst):
m, n = len(lst), len(seq)
for i in xrange(m):
for j in xrange(n):
if lst[i] == seq[j]:
if lst[i+1] == seq[j+1]:
if lst[i+2] == seq[j+2]:
return lst[i+3]
(我的意图是扩展这个函数,以便如果该序列在整个列表中出现不止一次,它应该返回序列后最常发生的后续项目)
答案 0 :(得分:2)
我会用发生器切片:
sequence = [1, 2, 3, 5, 1, 2, 3, 6, 1, 2, 3]
pattern = [1, 2, 3]
def find_item_after_pattern(sequence, pattern):
n = len(pattern)
for index in range(0, len(sequence) - n):
if pattern == sequence[index:index + n]:
yield sequence[index + n]
for item in find_item_after_pattern(sequence, pattern):
print(item)
你会得到:
5
6
该功能效率不高,不适用于无限序列,但它简短且通用。
答案 1 :(得分:1)
由于您要比较连续索引,并假设lst
和seq
属于同一类型,您可以使用切片:
def sequence_in_list(seq, lst):
m, n = len(lst), len(seq)
for i in xrange(m):
for j in xrange(n):
if lst[i:i+3] == seq[j:j+3]:
return lst[i+3]
如果序列属于不同类型,则应在进行比较之前转换为通用类型(例如,如果lst[i:i+3] == list(seq[j:j+3])
是字符串且seq
是列表,则lst
将起作用)。
或者,如果序列不支持切片,您可以使用内置的all
检查更多条件:
def sequence_in_list(seq, lst):
m, n = len(lst), len(seq)
for i in xrange(m):
for j in xrange(n):
if all(lst[i+k] == seq[j+k] for k in range(3)):
return lst[i+3]
如果您想将检查扩展到10个而不是3个,只需将range(3)
更改为range(10)
。
附注:您的原始代码会在某个时刻引发IndexError
,因为您访问的list[i+1]
i
可能是len(list) - 1
。上面的代码不会产生任何错误,因为切片可能会产生比索引差异更短的切片,seq[j:j+3]
可能少于3个元素。如果这是一个问题,您应该调整迭代的索引。
上次评论:请勿使用名称list
,因为它会隐藏内置名称。
答案 2 :(得分:0)
您可以将列表理解与切片结合起来,使比较更具可读性:
n, m = len(lst), len(seq)
[lst[j+3] for i in range(m-2) for j in range(n-2) if seq[i:i+3] == lst[j:j+3]]
当然有更有效的方法,但这很简单,简短,蟒蛇风格。