Rin*_*nce 29 python iteration loops slice
我想要一个算法迭代列表切片.切片大小设置在功能之外,可以有所不同.
在我看来它是这样的:
for list_of_x_items in fatherList:
foo(list_of_x_items)
Run Code Online (Sandbox Code Playgroud)
有没有办法正确定义list_of_x_items或使用python 2.5执行此操作的其他方法?
edit1:澄清 "分区"和"滑动窗口"这两个术语听起来都适用于我的任务,但我不是专家.所以我会更深入地解释这个问题并添加到问题中:
fatherList是我从文件中获取的多级numpy.array.函数必须找到系列的平均值(用户提供系列的长度)平均我正在使用该mean()函数.现在进行问题扩展:
edit2:如何修改你提供的函数来存储额外的项目,并在下一个fatherList被输入函数时使用它们?
例如,如果列表长度为10且块的大小为3,则列表的第10个成员将被存储并附加到下一个列表的开头.
Nad*_*mli 62
如果你想将列表分成片,你可以使用这个技巧:
list_of_slices = zip(*(iter(the_list),) * slice_size)
Run Code Online (Sandbox Code Playgroud)
例如
>>> zip(*(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]
Run Code Online (Sandbox Code Playgroud)
如果切片大小无法分割项目数,并且您希望使用"无"填充列表,则可以执行以下操作:
>>> map(None, *(iter(range(10)),) * 3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]
Run Code Online (Sandbox Code Playgroud)
这是一个肮脏的小技巧
好的,我会解释它是如何工作的.解释起来会很棘手,但我会尽我所能.
首先是一点背景:
在Python中,您可以将列表乘以如下数字:
[1, 2, 3] * 3 -> [1, 2, 3, 1, 2, 3, 1, 2, 3]
([1, 2, 3],) * 3 -> ([1, 2, 3], [1, 2, 3], [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
和迭代器对象可以像这样一次消耗:
>>> l=iter([1, 2, 3])
>>> l.next()
1
>>> l.next()
2
>>> l.next()
3
Run Code Online (Sandbox Code Playgroud)
的拉链函数返回的元组,其中,第i个元组包含来自每个参数序列或iterables的第i个元素的列表.例如:
zip([1, 2, 3], [20, 30, 40]) -> [(1, 20), (2, 30), (3, 40)]
zip(*[(1, 20), (2, 30), (3, 40)]) -> [[1, 2, 3], [20, 30, 40]]
Run Code Online (Sandbox Code Playgroud)
zip前面的*用于解包参数.你可以在这里找到更多细节.所以
zip(*[(1, 20), (2, 30), (3, 40)])
Run Code Online (Sandbox Code Playgroud)
实际上相当于
zip((1, 20), (2, 30), (3, 40))
Run Code Online (Sandbox Code Playgroud)
但使用可变数量的参数
现在回到诀窍:
list_of_slices = zip(*(iter(the_list),) * slice_size)
Run Code Online (Sandbox Code Playgroud)
iter(the_list) - >将列表转换为迭代器
(iter(the_list),) * N - >将生成对the_list迭代器的N引用.
zip(*(iter(the_list),) * N) - >将这些迭代器列表提供给zip.而这又将它们分组为N个大小的元组.但由于所有N个项实际上都是对同一个迭代器iter(the_list)的引用,因此结果将重复调用next()原始迭代器
我希望能够解释它.我建议你使用一个更容易理解的解决方案.我很想提到这个技巧,因为我喜欢它.
Ant*_*sma 21
如果您希望能够使用任何iterable,则可以使用以下函数:
from itertools import chain, islice
def ichunked(seq, chunksize):
"""Yields items from an iterator in iterable chunks."""
it = iter(seq)
while True:
yield chain([it.next()], islice(it, chunksize-1))
def chunked(seq, chunksize):
"""Yields items from an iterator in list chunks."""
for chunk in ichunked(seq, chunksize):
yield list(chunk)
Run Code Online (Sandbox Code Playgroud)
使用发电机:
big_list = [1,2,3,4,5,6,7,8,9]
slice_length = 3
def sliceIterator(lst, sliceLen):
for i in range(len(lst) - sliceLen + 1):
yield lst[i:i + sliceLen]
for slice in sliceIterator(big_list, slice_length):
foo(slice)
Run Code Online (Sandbox Code Playgroud)
sliceIterator实现一个宽度sliceLen超过序列的"滑动窗口" lst,即它产生重叠切片:[1,2,3],[2,3,4],[3,4,5],......不确定是否是但是OP的意图.
问题更新:如何修改你提供的功能来存储额外的项目,并在下一个fatherList被输入函数时使用它们?
如果您需要存储状态,那么您可以使用一个对象.
class Chunker(object):
"""Split `iterable` on evenly sized chunks.
Leftovers are remembered and yielded at the next call.
"""
def __init__(self, chunksize):
assert chunksize > 0
self.chunksize = chunksize
self.chunk = []
def __call__(self, iterable):
"""Yield items from `iterable` `self.chunksize` at the time."""
assert len(self.chunk) < self.chunksize
for item in iterable:
self.chunk.append(item)
if len(self.chunk) == self.chunksize:
# yield collected full chunk
yield self.chunk
self.chunk = []
Run Code Online (Sandbox Code Playgroud)
例:
chunker = Chunker(3)
for s in "abcd", "efgh":
for chunk in chunker(s):
print ''.join(chunk)
if chunker.chunk: # is there anything left?
print ''.join(chunker.chunk)
Run Code Online (Sandbox Code Playgroud)
输出:
abc
def
gh
Run Code Online (Sandbox Code Playgroud)
你的意思是:
def callonslices(size, fatherList, foo):
for i in xrange(0, len(fatherList), size):
foo(fatherList[i:i+size])
Run Code Online (Sandbox Code Playgroud)
如果这大致是您想要的功能,如果您愿意,可以在发电机中装扮一下:
def sliceup(size, fatherList):
for i in xrange(0, len(fatherList), size):
yield fatherList[i:i+size]
Run Code Online (Sandbox Code Playgroud)
然后:
def callonslices(size, fatherList, foo):
for sli in sliceup(size, fatherList):
foo(sli)
Run Code Online (Sandbox Code Playgroud)
我不确定,但似乎你想做所谓的移动平均线.numpy为此提供了设施(卷积函数).
>>> x = numpy.array(range(20))
>>> x
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
>>> n = 2 # moving average window
>>> numpy.convolve(numpy.ones(n)/n, x)[n-1:-n+1]
array([ 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5,
9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5])
好处是它可以很好地适应不同的加权方案(只需改变numpy.ones(n) / n其他东西).
您可以在这里找到完整的资料:http: //www.scipy.org/Cookbook/SignalSmooth