cpi*_*nco 2 python iterator list
该itertools Python模块实现了迭代器的一些基本构建块.正如他们所说,"它们构成了迭代器代数".我期待,但我找不到使用该模块进行以下迭代的简洁方法.例如,给出有序实数列表
a = [1.0,1.5,2.0,2.5,3.0]
Run Code Online (Sandbox Code Playgroud)
...返回一个新的列表(或只是迭代)按一些n值分组,比方说2
b = [(1.0,1.5),(1.5,2.0),(2.0,2.5),(2.5,3.0)]
Run Code Online (Sandbox Code Playgroud)
我发现这样做的方式如下.首先将列表分为两部分,使用均衡和赔率索引:
even, odds = a[::2], a[1::2]
Run Code Online (Sandbox Code Playgroud)
然后构造新的列表:
b = [(even, odd) for even, odd in zip(evens, odds)]
b = sorted(b + [(odd, even) for even, odd in zip(evens[1:], odds)])
Run Code Online (Sandbox Code Playgroud)
从本质上讲,它类似于移动平均值.
有没有简洁的方法(有或没有itertools)?
PS:
应用
将a列表想象为实验期间发生的一些事件的时间戳集:
timestamp event
47.8 1a
60.5 1b
67.4 2a
74.5 2b
78.5 1a
82.2 1b
89.5 2a
95.3 2b
101.7 1a
110.2 1b
121.9 2a
127.1 2b
...
Run Code Online (Sandbox Code Playgroud)
此代码用于根据不同的时间窗口对这些事件进行分段.现在我对2连续事件之间的数据感兴趣; 'n> 2'仅用于探索目的.
这正是pairwiseitertools配方的用途n=2.
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
Run Code Online (Sandbox Code Playgroud)
演示:
>>> b = [1.0,1.5,2.0,2.5,3.0]
>>> list(pairwise(b))
[(1.0, 1.5), (1.5, 2.0), (2.0, 2.5), (2.5, 3.0)]
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找变量组大小,请参阅user2357112的答案(我喜欢这种方法),或者更一般地说,您可以实现一个滑动窗口迭代器并采用有许多方法的切片.
顺便说一句,一个可能表现不佳但有趣的单行窗口,你可以切片(控制重叠)不在链接的问题上就是这样,使用新的yield from语法来组合生成器.
from itertools import tee, islice
def roll_window(it, sz):
yield from zip(*[islice(it, g, None) for g, it in enumerate(tee(it, sz))])
Run Code Online (Sandbox Code Playgroud)
演示:
>>> b = [1.0,1.5,2.0,2.5,3.0, 3.5, 4.0, 4.5]
>>> list(islice(window(b, 3), None, None, 2))
[(1.0, 1.5, 2.0), (2.0, 2.5, 3.0), (3.0, 3.5, 4.0)]
Run Code Online (Sandbox Code Playgroud)
对于2,你可以做到
b = zip(a, a[1:]) # or list(zip(...)) on Python 3 if you really want a list
Run Code Online (Sandbox Code Playgroud)
对于固定n,技术类似:
# n = 4
b = zip(a, a[1:], a[2:], a[3:])
Run Code Online (Sandbox Code Playgroud)
对于变量n,您可以压缩可变数量的切片,或者(特别是如果窗口大小接近大小a),您可以使用切片直接获取窗口:
b = zip(*[a[i:] for i in xrange(n)])
# or
b = [tuple(a[i:i+n]) for i in xrange(len(a)-n+1)]
Run Code Online (Sandbox Code Playgroud)
如果a不是列表,您可以pairwise从itertools文档中推广配方:
import copy
import itertools
def nwise(iterable, n):
# Make n tees at successive positions along the iterable.
tees = list(itertools.tee(iterable, 1))
for _ in xrange(n-1):
tees.append(copy.copy(tees[-1]))
next(tees[-1])
return zip(*tees)
Run Code Online (Sandbox Code Playgroud)