2010-09-30 35 views
5

Trăn tương đương với số each_slice(count) của Ruby là gì?
Tôi muốn lấy 2 phần tử từ danh sách cho mỗi lần lặp lại.
Thích cho [1,2,3,4,5,6] Tôi muốn xử lý 1,2 trong lần lặp đầu tiên sau đó 3,4 rồi 5,6.
ofcourse có một cách vòng xoay bằng cách sử dụng giá trị chỉ mục. Nhưng có một chức năng trực tiếp hoặc một cách nào đó để làm điều này trực tiếp?Python tương đương với mỗi số_lice của Ruby (đếm)

+0

câu trả lời của nhãn hiệu hoàn toàn đáp ứng các đặc điểm bạn đã cung cấp trong câu hỏi của mình. Tuy nhiên, điều quan trọng cần lưu ý là hành vi mà anh ta chỉ định lệch khỏi each_slice của ruby: Nếu slice cuối cùng ngắn hơn phần còn lại, nó sẽ được đệm với fillvalue, trong khi đó mỗi tệp là một mảng rút gọn. Nếu bạn muốn danh sách rút gọn này/hành vi có thể lặp lại, thì câu trả lời của Mark sẽ không hoạt động. – bwv549

Trả lời

9

Có một recipe cho điều này trong các itertools documentation gọi mú:

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) 

Sử dụng như thế này:

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

1 2 
3 4 
5 6 
+0

Lưu ý: sử dụng ** zip_longest ** thay vì ** izip_longest ** cho python 3. – bwv549

2

Tương tự như Mark nhưng đổi tên thành 'each_slice' và làm việc cho python 2 và 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

Sao chép hành vi each_slice của ruby ​​cho một trai nhỏ ling 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 

Câu trả lời ở trên sẽ liệt kê danh sách cuối cùng (ví dụ: [5, None]), có thể không phải là điều mong muốn trong một số trường hợp.

0

Cải thiện trên hai đầu tiên: Nếu có thể chia cắt được lặp lại không chính xác chia hết cho n, giá trị cuối cùng sẽ được điền vào độ dài n bằng Không. Nếu điều này gây ra lỗi cho bạn, bạn có thể thực hiện một thay đổi nhỏ:

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] 

Hãy nhớ rằng điều này sẽ không được sử dụng trong trường hợp Không có lỗi nào gây ra lỗi.

Các vấn đề liên quan