如何使用Python 2.7.1中的itertools、yield和iter()生成一个滑动窗口的字符串列表?

8
我是一名有用的助手,可以为您翻译文本。

我正在尝试在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'。”
我真的很困惑……

可能是Python分割移动窗口字符串的重复问题。 - Jon-Eric
5
兄弟...你打算每隔8个小时发布同样的问题吗?:o - mac
我的错,我以为我能够删除另一个。 - O.rka
这仍然是错误的:如果你提出一个问题,却没有得到答案,有可能是因为:(1)你表达得不够清楚[→修改它] - (2)这是一个困难的问题[→自己回答一些问题,获得声望点并在上面放置赏金]。重新发布以获取关注并不是SO所欢迎的行为(尽管我相信您没有出于任何恶意而这样做!) :) - mac
6个回答

17
你的意思是想要做这个吗?:
a='abcdefg'
b = [a[i:i+3] for i in xrange(len(a)-2)]
print b
['abc', 'bcd', 'cde', 'def', 'efg']

2
我们是否应该使用range而不是xrange以增强与Python 3的兼容性? - Clement H.
@ClementH。原始的 OP 是关于 Python2.7 安装的,因此在这种情况下,xrange 是最好的选择(对于内存消耗)。然而,在 Python3 中,range 将是最佳解决方案。如果您要迭代的数字不太大,请在任何地方使用 range,否则请使用 six - Cédric Julien

6

你的生成器可以更短:

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

这绝对是更好的选择。当时我不知道生成器是什么,也没有像现在这样处理大型数据集的经验。 - O.rka
在Python3中,xrange现在被称为range - neuron

2

使用一行代码中的zip函数:

  [ "".join(j) for j in zip(*[fseq[i:] for i in range(window_size)])]

1
def window(fseq,fn):
    alpha=[fseq[i:i+fn] for i in range(len(fseq)-(fn-1))]
    return alpha

0

我不知道你的输入或期望输出是什么,但你不能在一个函数中混合使用yieldreturn。将return改为yield,你的函数就不会再抛出那个错误了。

def window(fseq, window_size=5):
    ....
        final.append(tentative_string)
    yield final

0
>>>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)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接