Python相当于Ruby的each_slice(count)

时间:2010-09-30 18:19:19

标签: python ruby

什么是相当于Ruby each_slice(count)的蟒蛇? 我想从列表中获取每个迭代的2个元素 与[1,2,3,4,5,6]一样,我希望在第一次迭代中处理1,2,然后3,4然后5,6。 当然,使用索引值有一种迂回的方式。但有直接的功能或直接这样做吗?

6 个答案:

答案 0 :(得分:9)

recipe的石斑鱼中有一个itertools documentation

from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

像这样使用:

>>> l = [1,2,3,4,5,6]
>>> for a,b in grouper(2, l):
>>>     print a, b

1 2
3 4
5 6

答案 1 :(得分:2)

与Mark相同,但重命名为'each_slice'并适用于python 2和3:

try:
    from itertools import izip_longest  # python 2
except ImportError:
    from itertools import zip_longest as izip_longest  # python 3

def each_slice(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

答案 2 :(得分:1)

为小尾随切片复制ruby的each_slice行为:

def each_slice(size, iterable):
    """ Chunks the iterable into size elements at a time, each yielded as a list.

    Example:
      for chunk in each_slice(2, [1,2,3,4,5]):
          print(chunk)

      # output:
      [1, 2]
      [3, 4]
      [5]
    """
    current_slice = []
    for item in iterable:
        current_slice.append(item)
        if len(current_slice) >= size:
            yield current_slice
            current_slice = []
    if current_slice:
        yield current_slice

上面的答案将填写最后一个列表(即[5,无]),这可能不是某些情况下所需的。

答案 3 :(得分:0)

对前两个的改进:如果被切片的可迭代不能被n整除,则最后一个将被填充到长度为n的无。如果这导致您输入错误,则可以进行一些小改动:

def each_slice(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    raw = izip_longest(fillvalue=fillvalue, *args)
    return [filter(None, x) for x in raw]

请注意,这将从范围中移除所有无,因此只应在无效将导致错误的情况下使用。

答案 4 :(得分:0)

我知道许多语言专家已经回答了这个问题,但是我使用一种不同的方法使用生成器函数,该函数更易于阅读,并且可以根据您的需要进行推理和修改:

def each_slice(list: List[str], size: int):
    batch = 0
    while batch * size < len(list):
        yield list[batch * size:(batch + 1) * size]
        batch += 1   

slices = each_slice(["a", "b", "c", "d", "e", "f", "g"], 2)
print([s for s in slices])

$ [['a', 'b'], ['c', 'd'], ['e', 'f'], ['g']]

如果您需要每个切片都具有批处理大小,则可以填充None或某些默认字符,您可以简单地在收益中添加填充代码。如果要使用each_cons,则可以通过修改代码来逐个移动而不是逐批移动来实现。

答案 5 :(得分:0)

s_size = 4
l = list(range(100))

while len(l) > 0:
    slice = [l.pop() for _e,i in enumerate(l) if i <= s_size ]
    print(slice)