443,898 Members | 1,325 Online Need help? Post your question and get tips & solutions from a community of 443,898 IT Pros & Developers. It's quick & easy.

# better way to write this function

 P: n/a Hello, This function does I what I want. But I'm wondering if there is an easier/better way. To be honest, I don't have a good understanding of what "pythonic" means yet. def divide_list(lst, n): """Divide a list into a number of lists, each with n items. Extra items are ignored, if any.""" cnt = len(lst) / n rv = [[None for i in range(n)] for i in range(cnt)] for i in range(cnt): for j in range(n): rv[i][j] = lst[i * n + j] return rv Thanks! Nov 26 '07 #1
14 Replies

 P: n/a Kelie wrote: Hello, This function does I what I want. But I'm wondering if there is an easier/better way. To be honest, I don't have a good understanding of what "pythonic" means yet. def divide_list(lst, n): """Divide a list into a number of lists, each with n items. Extra items are ignored, if any.""" cnt = len(lst) / n rv = [[None for i in range(n)] for i in range(cnt)] for i in range(cnt): for j in range(n): rv[i][j] = lst[i * n + j] return rv You can use slicing: >>def chunks(items, n): .... return [items[start:start+n] for n in range(0, len(items)-n+1, n)] .... >>for i in range(1,10): .... print chunks(range(5), i) .... [, , , , ] [[0, 1], [2, 3]] [[0, 1, 2]] [[0, 1, 2, 3]] [[0, 1, 2, 3, 4]] [] [] [] [] Or build a generator that works with arbitrary iterables: >>from itertools import *def chunks(items, n): .... items = iter(items) .... while 1: .... chunk = list(islice(items, n-1)) .... chunk.append(items.next()) .... yield chunk .... >>list(chunks(range(5), 2)) [[0, 1], [2, 3]] Peter Nov 26 '07 #2

 P: n/a On Nov 26, 9:42 am, Kelie

 P: n/a Chris

 P: n/a On Nov 26, 10:51 am, Paul Rubin

 P: n/a Kelie

 P: n/a On Nov 25, 10:51 pm, Paul Rubin

 P: n/a On Nov 25, 11:24 pm, Paul Rudin

 P: n/a On Nov 26, 2007 3:24 AM, Paul Rudin

 P: n/a On Nov 26, 1:42 am, Kelie >lst = list("ABCDE")for j in range(1,6): .... print j,':',[lst[i:i+j] for i in xrange(0,len(lst),j)] .... 1 : [['A'], ['B'], ['C'], ['D'], ['E']] 2 : [['A', 'B'], ['C', 'D'], ['E']] 3 : [['A', 'B', 'C'], ['D', 'E']] 4 : [['A', 'B', 'C', 'D'], ['E']] 5 : [['A', 'B', 'C', 'D', 'E']] Or if you want to discard the uneven leftovers: >>for j in range(1,6): .... print j,':',[lst[i:i+j] for i in xrange(0,len(lst),j) if i +j<=len(lst)] .... 1 : [['A'], ['B'], ['C'], ['D'], ['E']] 2 : [['A', 'B'], ['C', 'D']] 3 : [['A', 'B', 'C']] 4 : [['A', 'B', 'C', 'D']] 5 : [['A', 'B', 'C', 'D', 'E']] Or define a lambda: >>chunksWithLeftovers = lambda lst,n: [lst[i:i+n] for i in xrange(0,len(lst),n)]chunksWithoutLeftovers = lambda lst,n: [lst[i:i+n] for i in xrange(0,len(lst),n) if i+n<=len(lst)]chunksWithLeftovers(lst,2) [['A', 'B'], ['C', 'D'], ['E']] >>chunksWithoutLeftovers(lst,2) [['A', 'B'], ['C', 'D']] -- Paul Nov 26 '07 #10

 P: n/a On Nov 26, 7:42 am, Kelie

 P: n/a Peter Otten wrote: >>>def chunks(items, n): ... return [items[start:start+n] for n in range(0, len(items)-n+1, n)] Ouch, this should be def chunks(items, n): return [items[start:start+n] for start in range(0, len(items)-n+1, n)] Peter Nov 26 '07 #12

 P: n/a On Nov 26, 8:19 am, Peter Otten <__pete...@web.dewrote: [...] > Or build a generator that works with arbitrary iterables: >from itertools import *def chunks(items, n): ... items = iter(items) ... while 1: ... chunk = list(islice(items, n-1)) ... chunk.append(items.next()) ... yield chunk ...>>list(chunks(range(5), 2)) [[0, 1], [2, 3]] Peter I was about to send this before I saw your post :) Well here it is anyway... Using the fact that StopIteration exceptions fall through list comprehensions (as opposed to islices): def chunks(iterable, size): next = iter(iterable).next while True: yield [next() for i in xrange(size)] -- Arnaud Nov 26 '07 #13

 P: n/a Peter Otten wrote: Kelie wrote: >Hello,This function does I what I want. But I'm wondering if there is aneasier/better way. To be honest, I don't have a good understanding ofwhat "pythonic" means yet.def divide_list(lst, n): """Divide a list into a number of lists, each with n items. Extraitems are ignored, if any.""" cnt = len(lst) / n rv = [[None for i in range(n)] for i in range(cnt)] for i in range(cnt): for j in range(n): rv[i][j] = lst[i * n + j] return rv You can use slicing: >>>def chunks(items, n): ... return [items[start:start+n] for n in range(0, len(items)-n+1, n)] ... >>>for i in range(1,10): ... print chunks(range(5), i) ... [, , , , ] [[0, 1], [2, 3]] [[0, 1, 2]] [[0, 1, 2, 3]] [[0, 1, 2, 3, 4]] [] [] [] [] This won't work(e.g. you don't define "start", you change the value of n through the loop). I guess you meant : def chunks(items, n) : return [items[i:i+n] for i in range(0, len(items)-n+1, n)] Nov 27 '07 #14

 P: n/a Ricardo ArÃ¡oz wrote: Peter Otten wrote: >You can use slicing: >>>>def chunks(items, n): ... return [items[start:start+n] for n in range(0, len(items)-n+1, n)]... >>>>for i in range(1,10): ... print chunks(range(5), i)...[, , , , ][[0, 1], [2, 3]][[0, 1, 2]][[0, 1, 2, 3]][[0, 1, 2, 3, 4]][][][][] This won't work(e.g. you don't define "start", you change the value of n through the loop). I guess you meant : def chunks(items, n) : return [items[i:i+n] for i in range(0, len(items)-n+1, n)] Indeed; I'm still wondering how I managed to copy'n'paste the version with the typo together with the demo of the correct one. Peter Nov 27 '07 #15

### This discussion thread is closed

Replies have been disabled for this discussion. 