迭代列表切片
我想要一个算法来迭代列表切片。切片大小在函数外部设置并且可以不同。
在我看来,它是这样的:
for list_of_x_items in fatherList:
foo(list_of_x_items)
有没有办法正确定义 list_of_x_items
或使用 python 2.5 执行此操作的其他方式?
编辑1:澄清“分区”和“滑动窗口”术语听起来都适用于我的任务,但我不是专家。所以我将更深入地解释这个问题并添加到问题中:
fatherList 是我从文件中获取的多级 numpy.array 。函数必须找到系列的平均值(用户提供系列的长度)为了求平均值,我使用 mean()
函数。现在进行问题扩展:
edit2:如何修改您提供的函数来存储额外的项目,并在下一个fatherList输入到该函数时使用它们?
例如,如果列表的长度为 10 并且块的大小为 3,则存储列表的第 10 个成员并将其附加到下一个列表的开头。
相关:
I want an algorithm to iterate over list slices. Slices size is set outside the function and can differ.
In my mind it is something like:
for list_of_x_items in fatherList:
foo(list_of_x_items)
Is there a way to properly define list_of_x_items
or some other way of doing this using python 2.5?
edit1: Clarification Both "partitioning" and "sliding window" terms sound applicable to my task, but I am no expert. So I will explain the problem a bit deeper and add to the question:
The fatherList is a multilevel numpy.array I am getting from a file. Function has to find averages of series (user provides the length of series) For averaging I am using the mean()
function. Now for question expansion:
edit2: How to modify the function you have provided to store the extra items and use them when the next fatherList is fed to the function?
for example if the list is lenght 10 and size of a chunk is 3, then the 10th member of the list is stored and appended to the beginning of the next list.
Related:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
扩展@Ants Aasma的答案:在Python 3.7中,
StopIteration
异常的处理更改(根据 PEP-479< /a>)。兼容版本是:Expanding on the answer of @Ants Aasma: In Python 3.7 the handling of the
StopIteration
exception changed (according to PEP-479). A compatible version would be:你的问题可以使用更多细节,但是怎么样:
Your question could use some more detail, but how about:
对于一个近乎一个的衬垫(在
itertools
导入之后),按照Nadia的答案处理非块可整除尺寸而无需填充:如果你愿意,你可以摆脱
itertools.count ()
要求使用enumerate()
,但比较丑陋:(在本例中,
enumerate()
是多余的,但并非所有序列都是整齐的范围就像这样,显然)远没有其他答案那么简洁,但在紧要关头很有用,特别是如果已经导入了itertools。
For a near-one liner (after
itertools
import) in the vein of Nadia's answer dealing with non-chunk divisible sizes without padding:If you want, you can get rid of the
itertools.count()
requirement usingenumerate()
, with a rather uglier:(In this example the
enumerate()
would be superfluous, but not all sequences are neat ranges like this, obviously)Nowhere near as neat as some other answers, but useful in a pinch, especially if already importing
itertools
.将列表或迭代器分割成给定大小的块的函数。如果最后一个块较小,也可以正确处理这种情况:
用法示例:
结果:
A function that slices a list or an iterator into chunks of a given size. Also handles the case correctly if the last chunk is smaller:
Usage example:
Result:
如果你想将列表分成切片,你可以使用这个技巧:
例如,
如果项目的数量不能被切片大小整除,并且你想用 None 填充列表,你可以这样做:
这是一个肮脏的小技巧
OK ,我将解释它是如何工作的。解释起来会很棘手,但我会尽力。
首先是一些背景知识:
在 Python 中,您可以将列表乘以数字,如下所示:
以及 迭代器 对象可以像这样使用一次:
zip 函数返回一个元组列表,其中第 i 个元组包含每个参数序列或可迭代对象中的第 i 个元素。例如:
zip 前面的 * 用于解压参数。您可以在此处找到更多详细信息。
So
实际上相当于
但可以使用可变数量的参数
现在回到技巧:
iter(the_list)
->将列表转换为迭代器(iter(the_list),) * N
->将生成对 the_list 迭代器的 N 引用。zip(*(iter(the_list),) * N)
->会将这些迭代器列表输入 zip 中。这又会将它们分组为 N 大小的元组。但由于所有 N 个项目实际上都是对同一个迭代器iter(the_list)
的引用,因此结果将在原始迭代器上重复调用next()
我希望能解释这一点。我建议您采用更容易理解的解决方案。我只是想提及这个技巧,因为我喜欢它。
If you want to divide a list into slices you can use this trick:
For example
If the number of items is not dividable by the slice size and you want to pad the list with None you can do this:
It is a dirty little trick
OK, I'll explain how it works. It'll be tricky to explain but I'll try my best.
First a little background:
In Python you can multiply a list by a number like this:
And an iterator object can be consumed once like this:
The zip function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. For example:
The * in front of zip used to unpack arguments. You can find more details here.
So
is actually equivalent to
but works with a variable number of arguments
Now back to the trick:
iter(the_list)
-> convert the list into an iterator(iter(the_list),) * N
-> will generate an N reference to the_list iterator.zip(*(iter(the_list),) * N)
-> will feed those list of iterators into zip. Which in turn will group them into N sized tuples. But since all N items are in fact references to the same iteratoriter(the_list)
the result will be repeated calls tonext()
on the original iteratorI hope that explains it. I advice you to go with an easier to understand solution. I was only tempted to mention this trick because I like it.
如果您希望能够使用任何可迭代对象,您可以使用以下函数:
If you want to be able to consume any iterable you can use these functions:
使用生成器:
sliceIterator
在序列lst
上实现宽度为sliceLen
的“滑动窗口”,即它生成重叠切片:[1,2 ,3],[2,3,4],[3,4,5],...但不确定这是否是OP的意图。Use a generator:
sliceIterator
implements a "sliding window" of widthsliceLen
over the squencelst
, i.e. it produces overlapping slices: [1,2,3], [2,3,4], [3,4,5], ... Not sure if that is the OP's intention, though.您的意思是:
如果这大致是您想要的功能,如果您愿意,您可以在生成器中对其进行一些修饰:
然后:
Do you mean something like:
If this is roughly the functionality you want you might, if you desire, dress it up a bit in a generator:
and then:
回答问题的最后一部分:
如果您需要存储状态,那么您可以使用对象来存储状态。
示例:
输出:
Answer to the last part of the question:
If you need to store state then you can use an object for that.
Example:
Output:
我不确定,但你似乎想做所谓的移动平均线。 numpy 为此提供了工具(卷积函数)。
好处是它可以很好地适应不同的权重方案(只需将 numpy.ones(n) / n 更改为其他内容即可)。
您可以在这里找到完整的材料:
http://www.scipy.org/Cookbook/SignalSmooth
I am not sure, but it seems you want to do what is called a moving average. numpy provides facilities for this (the convolve function).
The nice thing is that it accomodates different weighting schemes nicely (just change
numpy.ones(n) / n
to something else).You can find a complete material here:
http://www.scipy.org/Cookbook/SignalSmooth