2015-12-18 11 views
6

Với một danh sách đầu vàoCác mục nhóm của danh sách có python kích thước bước?

l = [1 2 3 4 5 6 7 8 9 10] 

và kích thước nhóm grp và từng bước

grp = 3; step = 2 

Tôi muốn trả về một danh sách. Lưu ý sự lặp lại ở phần cuối

1 2 3 
3 4 5 
5 6 7 
7 8 9 
9 10 1 

hoặc nếu

grp= 4; step = 2 

Sản lượng nên

1 2 3 4 
3 4 5 6 
5 6 7 8 
7 8 9 10 

Đây là mã tôi đến với nó không làm điều cyclic. Nhưng muốn biết nếu có một nhỏ hơn hoặc một giải pháp đơn giản hơn

def grouplist(l,grp,step): 
    oplist = list() 
    for x in range(0,len(l)): 
     if (x+grp<len(l)): 
     oplist.append(str(l[x:x+grp])) 
    return oplist 
+0

Đối với tôi cuộc xung đột hai ví dụ. Vui lòng hiển thị một bước cho bước = 1. Hay là ví dụ 1 nên là gì? – Pynchia

+0

@Pynchia hai ví dụ không xung đột. Cả hai đều có 'step = 2' nên số đầu tiên trên hàng thứ hai phải là' 3'. – SirParselot

+3

Tại sao cho grp 4 bước 2 chúng ta quấn lại khoảng 1 thay vì 10? – wim

Trả lời

3

Bạn có thể tận dụng lợi thế của hàm bước trong xrange hoặc dải ô dựa vào những gì phiên bản của python bạn đang sử dụng. Sau đó, để quấn lại xung quanh chỉ mod bởi độ dài của danh sách như vậy

import sys 

def grouplist(l,grp,step): 
    newlist=[] 
    d = len(l) 
    for i in xrange(0,len(l),step): 
     for j in xrange(grp): 
      newlist.append(l[(i+j)%d]) 
      sys.stdout.write(str(l[(i+j)%d]) + ' ') 
     print 

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
print grouplist(l,3,2) 
1 2 3 
3 4 5 
5 6 7 
7 8 9 
9 10 1 
[1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 1] 

print grouplist(l,4,2) 
1 2 3 4 
3 4 5 6 
5 6 7 8 
7 8 9 10 
9 10 1 2 
[1, 2, 3, 4, 3, 4, 5, 6, 5, 6, 7, 8, 7, 8, 9, 10, 9, 10, 1, 2] 
+0

Cảm ơn Nhưng tôi cũng có một câu hỏi tiếp theo. Tôi thực sự làm điều này cho các chuỗi và kết quả tôi nhận được ở dạng ['0_1iffon.jpg', '0_1_126.jpg', '0_1_127.jpg'] ['0_1_126.jpg', '0_1_127.jpg', '0_1_128.jpg'] ['0_1_127.jpg', '0_1_128.jpg', '0_1_129.jpg'] Bạn có biết cách tôi có thể xóa 'và [] và dấu phẩy không ?? –

+0

@ArsenalFanatic đối với tôi có vẻ như đây là danh sách các danh sách mà bạn có thể loại bỏ ''[]' bằng cách in chúng thay vì tự in danh sách. – SirParselot

2
def grouplist(L, grp, step): 
    starts = range(0, len(L), step) 
    stops = [x + grp for x in starts] 
    groups = [(L*2)[start:stop] for start, stop in zip(starts, stops)] 
    return groups 

def tabulate(groups): 
    print '\n'.join(' '.join(map(str, row)) for row in groups) 
    print 

đầu ra Ví dụ:

>>> tabulate(grouplist(range(1,11), 3, 2)) 
1 2 3 
3 4 5 
5 6 7 
7 8 9 
9 10 1 

>>> tabulate(grouplist(range(1,11), 4, 2)) 
1 2 3 4 
3 4 5 6 
5 6 7 8 
7 8 9 10 
9 10 1 2 
2

sử dụng một deque:

from itertools import islice 
from collections import deque 



def grps(l, gps, stp): 
    d = deque(l) 
    for i in range(0, len(l), stp): 
     yield list(islice(d, gps)) 
     d.rotate(-stp) 

đầu ra:

In [7]: l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

In [8]: list(grps(l, 3, 2)) 
Out[8]: [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10, 1]] 

In [9]: list(grps(l, 4, 2)) 
Out[9]: [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 1, 2]] 

Bạn cũng có thể tham gia mang lại đối tượng islice và quyết định những gì bạn muốn làm gì với nó bên ngoài:

def grps(l, gps, stp): 
    d = deque(l) 
    for i in range(0, len(l), stp): 
     yield islice(d, gps) 
     d.rotate(-stp) 

Output:

In [11]:  for gp in grps(l, 3,2): 
    ....:    print(" ".join(map(str,gp))) 
    ....:  
1 2 3 
3 4 5 
5 6 7 
7 8 9 
9 10 1 

Hoặc chỉ với modulo:

def grps(l, gps, stp): 
    ln = len(l) 
    for i in range(0, len(l), stp): 
     yield (l[j % ln] for j in range(i, i + gps)) 


for gp in grps(l, 4, 2): 
    print(" ".join(map(str, gp))) 
+2

@Padraic ... Tôi đã làm việc cho một cái gì đó giống như câu trả lời của bạn nhưng bạn vượt qua tôi ... tuyệt vời ... :) –

+2

Ý tưởng deque là tốt đẹp. – wim

+1

@PadraicCunningham ... Tâm Chia sẻ một số tài nguyên về cách làm việc với các mô-đun và bộ sưu tập itertools..và tôi đã theo dõi câu trả lời của bạn và tôi thấy rằng bạn đang sử dụng rất nhiều phương pháp của họ ... cảm ơn ..:) –

0

Đây là một giải pháp khác, không sử dụng các chỉ mục trong danh sách khi quét nó. Thay vào đó, nó sẽ lưu các phần tử gặp phải được lặp lại và nối chúng với các phần tử theo sau.

def grplst(l, grp, stp): 
    ret = [] 
    saved = [] 
    curstp = 0 
    dx = grp - stp 
    for el in l: 
     curstp += 1 
     if curstp <= stp: 
      ret.append(el) 
     else: 
      saved.append(el) 
      if curstp >= grp: 
       yield ret+saved 
       ret = saved 
       saved = [] 
       curstp = dx 
    yield ret+l[:dx] 


l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

for g in grplst(l, 3, 2): 
    print(g) 

for g in grplst(l, 4, 2): 
    print(g) 

sản xuất

[1, 2, 3] 
[3, 4, 5] 
[5, 6, 7] 
[7, 8, 9] 
[9, 10, 1] 

[1, 2, 3, 4] 
[3, 4, 5, 6] 
[5, 6, 7, 8] 
[7, 8, 9, 10] 
[9, 10, 1, 2] 
1

Gói iteration_utilities có chức năng cho các loại hình trượt cửa sổ chiết successive:

from iteration_utilities import successive 
from itertools import chain, islice, starmap 

def wrapped_and_grouped_with_step(seq, groupsize, step, formatting=False): 
    padded = chain(seq, seq[:step-1]) 
    grouped = successive(padded, groupsize) 
    stepped = islice(grouped, None, None, step) 
    if formatting: 
     inner_formatted = starmap(('{} '*groupsize).strip().format, stepped) 
     outer_formatted = '\n'.join(inner_formatted) 
     return outer_formatted 
    else: 
     return stepped 

Áp dụng điều này để ví dụ của bạn:

>>> list(wrapped_and_grouped_with_step(l, 3, 2)) 
[(1, 2, 3), (3, 4, 5), (5, 6, 7), (7, 8, 9), (9, 10, 1)] 

>>> list(wrapped_and_grouped_with_step(l, 4, 2)) 
[(1, 2, 3, 4), (3, 4, 5, 6), (5, 6, 7, 8), (7, 8, 9, 10)] 

>>> print(wrapped_and_grouped_with_step(l, 3, 2, formatting=True)) 
1 2 3 
3 4 5 
5 6 7 
7 8 9 
9 10 1 

>>> print(wrapped_and_grouped_with_step(l, 4, 2, formatting=True)) 
1 2 3 4 
3 4 5 6 
5 6 7 8 
7 8 9 10 

Các gói phần mềm cũng bao gồm một lớp tiện ManyIterables:

>>> from iteration_utilities import ManyIterables 
>>> step, groupsize = 2, 4 
>>> print(ManyIterables(l, l[:step-1]) 
...  .chain() 
...  .successive(groupsize) 
...  [::step] 
...  .starmap(('{} '*groupsize).strip().format) 
...  .as_string('\n')) 
1 2 3 4 
3 4 5 6 
5 6 7 8 
7 8 9 10 

Lưu ý rằng các hoạt động này rất đánh giá được hoãn lại cho đến khi bạn lặp trên nó (ví dụ bằng cách tạo ra một list) dựa máy phát điện-.


Lưu ý rằng tôi là tác giả của iteration_utilities. Có một số gói khác cũng cung cấp chức năng tương tự, ví dụ: more-itertoolstoolz

0

Tính đến phiên bản 2.5, hỗ trợ more_itertools.windowed một từ khóa step.

> pip install more_itertools 

Ứng dụng:

import itertools as it 

import more_itertools as mit 

def grouplist(l, grp, step): 
    """Yield a finite number of windows.""" 
    iterable = it.cycle(l) 
    cycled_windows = mit.windowed(iterable, grp, step=step) 
    last_idx = grp - 1 
    for i, window in enumerate(cycled_windows): 
     yield window 
     if last_idx >= len(l) - 1: 
      break 
     last_idx += (i * step) 


list(grouplist(l, 3, 2)) 
# Out: [(1, 2, 3), (3, 4, 5), (5, 6, 7), (7, 8, 9), (9, 10, 1)] 

list(grouplist(l, 4, 2)) 
# Out: [(1, 2, 3, 4), (3, 4, 5, 6), (5, 6, 7, 8), (7, 8, 9, 10)] 

list(mit.flatten(grouplist(l, 3, 2))))     # optional 
# Out: [1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 1] 
2
[(l+l)[x:x+grp] for x,_ in list(enumerate(l))[::step]] 

hiện các trick trong một dòng

+0

Điều này là khá mát mẻ – pylang

+0

Tuy nhiên, cần lưu ý rằng thực hiện 'l + l' _each iteration_ là đáng kinh ngạc không hiệu quả! – MSeifert

+0

l2 = l + l; [l2 [x: x + grp] cho x, _ trong danh sách (liệt kê (l)) [:: bước]] giải quyết vấn đề – louis35

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