代码之家  ›  专栏  ›  技术社区  ›  theReverseFlick

python相当于ruby的每个片(count)

  •  6
  • theReverseFlick  · 技术社区  · 15 年前

    蟒蛇相当于红宝石的是什么? each_slice(count) ?
    我想从列表中为每个迭代取两个元素。
    喜欢 [1,2,3,4,5,6] 我想处理 1,2 在第一次迭代中,然后 3,4 然后 5,6
    当然,使用索引值有一种迂回的方法。但是是否有直接的函数或者某种方法可以直接做到这一点?

    5 回复  |  直到 7 年前
        1
  •  9
  •   Mark Byers    15 年前

    有一个 recipe 为了这个在 itertools documentation 调用的Grouper:

    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
    
        2
  •  2
  •   bwv549    11 年前

    与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)
    
        3
  •  1
  •   bwv549    11 年前

    为一个小的尾随切片复制Ruby的每个切片行为:

    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,无]),这在某些情况下可能不是所需的。

        4
  •  0
  •   Shay    8 年前

    前两个的一个改进:如果被切片的不可数不完全可以被n整除,那么最后一个将被填充到长度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]
    

    请记住,这将删除范围内的所有“无”,因此只应在没有任何“无”会导致错误的情况下使用。

        5
  •  0
  •   nurettin João    7 年前

    我知道这已经得到了语言方面的多个专家的回答,但是我有一种不同的方法,即使用一个更容易阅读和推理的生成器函数,并根据您的需要进行修改:

    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']]
    

    如果您需要每个切片都是批处理大小的,可以不填充,也可以添加一些默认字符,您可以简单地将填充代码添加到成品中。如果您想让每一个缺点代替,您可以通过修改代码来做到这一点,将代码逐个移动,而不是逐批移动。

    推荐文章