2010-09-30 20 views
5

Ruby'nin each_slice(count) ait piton eşdeğer nedir (sayım)?
Her yineleme için listeden 2 öğe almak istiyorum.
[1,2,3,4,5,6] için Gibi ilk iterasyonda 1,2 ve daha sonra 5,63,4 işlemek istiyorum.
Tabaka dizin değerlerini kullanarak dolambaçlı bir yol var. Ama bunu doğrudan yapmak için doğrudan bir işlev mi yoksa bir yol mu var?Ruby'nin each_slice Python eşdeğer

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) 

Kullanım böyle: Orfoz denilen itertools documentation bunun için bir recipe vardır

+0

mark'ın cevabı, sorunuzda sağladığınız özellikleri tam olarak karşılar. Bununla birlikte, belirttiği davranış, ruby'nin her_slice'den saptığını not etmek önemlidir: Son dilim kalandan daha kısa ise, doluluk değeri ile doldurulur, oysa ruby'nin her_slice'sinde sadece kısaltılmış bir dizidir. Bu kısaltılmış liste/yinelenen davranışı istiyorsanız, Mark'ın cevabı işe yaramaz. – bwv549

cevap

9

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

1 2 
3 4 
5 6 
+0

Not: python 3 için ** izip_longest ** yerine ** zip_longest ** kullanın. – bwv549

2

Mark'ın aynısı, ancak 'each_slice' olarak değiştirildi ve piton 2 ve 3 için çalışıyor :

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'nin her_slice davranışını küçük bir trai için çoğaltır Ling dilim: eğer yastık üzerinde

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 

soru son liste (yani, [5, Yok]), bazı durumlarda, istenen şey olmayabilir olan.

0

ilk ikisine bir iyileştirme: dilimlenmiş olan iterable n tarafından bölünebilen tam değilse, son Hiçbiri ile uzunluk n doldurulacaktır.

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] 

bu TÜM Yok aralığından var kaldıracaktır unutmayın, bu nedenle Yok yolda hatalara neden olur nerede sadece durumlarda kullanılmalıdır: Eğer hataları tipi neden olan bu ise, küçük bir değişiklik yapabilir.