从列表

时间:2017-09-18 15:16:04

标签: python python-3.x itertools

给出一个清单:

import string
a = list(string.ascii_lowercase)

返回 m 元素的每个第n个块的Pythonic方法是什么?请注意,这与仅返回every nth element不同。

获取每个 3个3个元素中的第1个元素的结果(取3,跳过6,取3,跳过6 ......):

['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u']

我可以这样做:

import itertools
s1 = a[::9]
s2 = a[1::9]
s3 = a[2::9]    
res = list(itertools.chain.from_iterable(zip(s1,s2, s3)))

有更清洁的方式吗?

6 个答案:

答案 0 :(得分:3)

对于select和skip的固定顺序,你可以将取模的索引包装在窗口的总长度上(这里是9)并且只选择那些低于给定阈值的那些,3:

lst = [x for i, x in enumerate(a) if i % 9 < 3]
print(lst)
# ['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u']

您可以将其变为一个使其更直观易用的功能:

def select_skip(iterable, select, skip):
    return [x for i, x in enumerate(iterable) if i % (select+skip) < select]  

print(select_skip(a, select=3, skip=6))
# ['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u']

答案 1 :(得分:2)

也许只写一个简单的生成器是最易读的

def thinger(iterable, take=3, skip=6):
    it = iter(iterable)
    try:
        while True:
            for i in range(take):
                yield next(it)
            for i in range(skip):
                next(it)
    except StopIteration:
        return

即使输入是无限的,也不是可切片的(例如,来自套接字的数据),这具有工作的优点。

答案 2 :(得分:2)

more_itertools是第三方库,用于实施itertools recipes和其他有用的工具,例如more_itertools.windowed

streams

代码

>  pip install more_itertools

import string from more_itertools import windowed, flatten m, n = 3, 6 list(flatten(windowed(string.ascii_lowercase, m, step=m+n))) # ['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u'] 每次迭代自然会占一个位置。通过推进超出重叠(windowed)的新步骤,可以适当地确定窗口。

答案 3 :(得分:0)

您可以使用某些generic "chunks" recipe

来执行此操作
windows = chunks(original_iter, n=3)

现在,您已经按照自己的想法为数据提供了数据,请使用islice's second variant来查找数据。 &#39;步骤&#39;功能:

# flattens the list as well using chain
result = chain.from_iterable(islice(windows, 0, None, 2))

答案 4 :(得分:0)

您可以使用列表推导并创建一个函数来执行任何跳过,获取和列出值:

import string
import itertools
a = list(string.ascii_lowercase)
def everyNthBlock(a, take, skip):
  res = [a[i:i + take] for i in range(0, len(a) ,skip + take)]
  return list(itertools.chain(*res))

print(everyNthBlock(a, 3, 6))
#^^^^ => ['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u']
print(everyNthBlock(a, 4, 7))
#^^^^ => ['a', 'b', 'c', 'd', 'l', 'm', 'n', 'o', 'w', 'x', 'y', 'z']

答案 5 :(得分:0)

使用难以理解的列表理解:D

m, n = 3, 3
[elem for blockstart in range(0, len(a), m*n) for elem in a[blockstart:blockstart+n]]    
#> ['a', 'b', 'c', 'j', 'k', 'l', 's', 't', 'u']