2010-09-30 106 views
5

什麼是Ruby的each_slice(count)等效的python?
我想從每個迭代列表中取2個元素。
[1,2,3,4,5,6]我想在第一次迭代處理1,2然後3,4然後5,6
當然有一個使用指數值的迂迴路線。但是有直接的功能還是直接做到這一點?Python的等價物Ruby的each_slice(count)

+0

mark的回答完全符合您在問題中提供的規範。然而,需要注意的是,他指定的行爲偏離了ruby的each_slice:如果最後一個片段比其餘片段短,它將填充fillvalue,而在ruby的each_slice中,它僅僅是一個縮短的數組。如果你想要這個縮短的列表/可迭代行爲,那麼馬克的答案將不起作用。 – bwv549 2015-08-24 16:39:51

回答

9

有一個在itertools documentation此一recipe叫石斑魚:

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 
+0

注意:使用** zip_longest **而不是** izip_longest **作爲python 3。 – bwv549 2014-11-25 17:30:50

2

同馬克的,但改名爲 '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) 
0

複製ruby的each_slice行爲爲一個小trai靈切片:

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,無]),這可能不是所期望的在某些情況下。

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] 

請記住,這將刪除所有無距離的範圍內的,所以只應在情況下使用都不會導致在路上的錯誤。