在 Python 2.7.1 中使用 itertools、yield 和 iter() 生成带有滑动窗口的字符串列表?
Posted
技术标签:
【中文标题】在 Python 2.7.1 中使用 itertools、yield 和 iter() 生成带有滑动窗口的字符串列表?【英文标题】:Generate a list of strings with a sliding window using itertools, yield, and iter() in Python 2.7.1? 【发布时间】:2012-01-14 12:56:45 【问题描述】:我正在尝试在 Python 中生成滑动窗口函数。我想出了如何做到这一点,但不是全部在函数内部。 itertools、yield 和 iter() 对我来说是全新的。
我要输入
a='abcdefg'
b=window(a,3)
print b
['abc','bcd','cde','def','efg']
我的工作方式是
def window(fseq, window_size=5):
import itertools
tentative=[]
final=[]
iteration=iter(fseq)
value=tuple(itertools.islice(iteration,window_size))
if len(value) == window_size:
yield value
for element in iteration:
value = value[1:] + (element,)
yield value
a='abcdefg'
result=window(a)
list1=[]
for k in result:
list1.append(k)
list2=[]
for j in list1:
tentative=''.join(j)
list2.append(tentative)
print list2
基本上让我困惑的是如何在函数内部使用函数的最终值?
这是我的函数代码
def window(fseq, window_size=5):
import itertools
tentative=[]
final=[]
iteration=iter(fseq)
value=tuple(itertools.islice(iteration,window_size))
if len(value) == window_size:
yield value
for element in iteration:
value = value[1:] + (element,)
yield value
for k in value:
tentative.append(k)
for j in tentative:
tentative_string=''.join(j)
final.append(tentative_string)
return final
seq='abcdefg'
uence=window(seq)
print uence
我希望它返回加入的列表,但是当我按下运行它时,它说“你的程序中有一个错误 * 'return' with argument inside generator”
我真的很困惑。 . .
【问题讨论】:
Python split string in moving window 的可能重复项 老兄...你打算每 8 小时发布一次相同的问题吗? :o 我的错我以为我可以删除另一个 它仍然是错误的:如果你问一个问题并且你没有得到答案,机会是:(1)你的表述很糟糕[→编辑它]-(2)这是一个困难的问题[ → 回答自己一些问题,获得声望点数并悬赏]。在 SO 上转发以获得关注并不是一个受欢迎的行为(尽管我很肯定你这样做并不是为了造成任何伤害!):) 【参考方案1】:def window(fseq,fn):
alpha=[fseq[i:i+fn] for i in range(len(fseq)-(fn-1))]
return alpha
【讨论】:
【参考方案2】:你的意思是你想这样做? :
a='abcdefg'
b = [a[i:i+3] for i in xrange(len(a)-2)]
print b
['abc', 'bcd', 'cde', 'def', 'efg']
【讨论】:
我们应该使用 range 来代替 xrange 来更好地兼容 python 3 吗? @ClementH。原始 OP 是关于 python2.7 安装的,所以在这种情况下,xrange
是最好的(用于内存消耗)。然而,在 python3 中,range
将是最好的解决方案。如果您没有太大的数字可以迭代,请在任何地方保留range
,否则,请使用six。【参考方案3】:
我不知道您的输入或预期输出是什么,但您不能将yield
和return
混合在一个函数中。将return
更改为yield
,您的函数将不会再次抛出该错误。
def window(fseq, window_size=5):
....
final.append(tentative_string)
yield final
【讨论】:
【参考方案4】:您的生成器可能会更短:
def window(fseq, window_size=5):
for i in xrange(len(fseq) - window_size + 1):
yield fseq[i:i+window_size]
for seq in window('abcdefghij', 3):
print seq
abc
bcd
cde
def
efg
fgh
ghi
hij
【讨论】:
这绝对是更好的选择。我当时不知道生成器是什么,也不必像现在这样处理大型数据集 在 python3 中,xrange
现在只是 range
【参考方案5】:
在一行代码中使用zip功能:
[ "".join(j) for j in zip(*[fseq[i:] for i in range(window_size)])]
【讨论】:
【参考方案6】:>>>def window(data, win_size):
... tmp = [iter(data[i:]) for i in range(win_size)]
... return zip(*tmp)
>>> a = [1, 2, 3, 4, 5, 6]
>>> window(a, 3)
>>>[(1,2,3), (2,3,4), (3,4,5), (4,5,6)]
【讨论】:
以上是关于在 Python 2.7.1 中使用 itertools、yield 和 iter() 生成带有滑动窗口的字符串列表?的主要内容,如果未能解决你的问题,请参考以下文章