在 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】:

我不知道您的输入或预期输出是什么,但您不能将yieldreturn 混合在一个函数中。将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() 生成带有滑动窗口的字符串列表?的主要内容,如果未能解决你的问题,请参考以下文章

腾讯蓝鲸cmdb源码编译

python安装postgresql驱动

Windows系统下Python环境的搭建

MyEclipse10配置PyDev进行Python开发

cxfreeze 找不到 libpyside-python

Python数据类型一