better way to write this function | | |
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! | | | | re: better way to write this function
Kelie wrote: Quote:
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: Quote: Quote: Quote:
>>def chunks(items, n):
.... return [items[start:start+n] for n in range(0, len(items)-n+1, n)]
.... Quote: Quote: Quote:
>>for i in range(1,10):
.... print chunks(range(5), i)
....
[[0], [1], [2], [3], [4]]
[[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: Quote: Quote: Quote:
>>from itertools import *
>>def chunks(items, n):
.... items = iter(items)
.... while 1:
.... chunk = list(islice(items, n-1))
.... chunk.append(items.next())
.... yield chunk
.... Quote: Quote: Quote:
>>list(chunks(range(5), 2))
[[0, 1], [2, 3]]
Peter | | | | re: better way to write this function
On Nov 26, 9:42 am, Kelie <kf9...@gmail.comwrote: Quote:
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!
x = ['1', '2', '3', '4', '5', '6', '7', '8']
def divide_list(lst, n):
rv = []
for i in range(int(round((len(lst)/n),0))):
rv.append(lst[i*n:(i+1)*n])
return rv
tmp = divide_list(x, 3)
tmp
[['1', '2', '3'], ['4', '5', '6']]
One way to do it. | | | | re: better way to write this function
Chris <cwitts@gmail.comwrites: Quote:
for i in range(int(round((len(lst)/n),0))): ...
Ugh!!! Not even correct (under future division), besides being ugly.
I think you mean:
for i in xrange(len(lst) // n): ...
Really though, this grouping function gets reimplemented so often that
it should be built into the stdlib, maybe in itertools. | | | | re: better way to write this function
On Nov 26, 10:51 am, Paul Rubin <http://phr...@NOSPAM.invalidwrote: Quote:
Chris <cwi...@gmail.comwrites: Quote:
for i in range(int(round((len(lst)/n),0))): ...
>
Ugh!!! Not even correct (under future division), besides being ugly.
I think you mean:
>
for i in xrange(len(lst) // n): ...
>
Really though, this grouping function gets reimplemented so often that
it should be built into the stdlib, maybe in itertools.
Beauty is in the eye of the beholder, but true... Looks crap :p | | | | re: better way to write this function
Kelie <kf9150@gmail.comwrites: Quote:
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!
See the last recipe from: http://docs.python.org/lib/itertools-recipes.html. It's not doing
quite the same thing, but gives an illustration of one way to approach
this sort of thing. | | | | re: better way to write this function
On Nov 25, 10:51 pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote: Quote:
Really though, this grouping function gets reimplemented so often that
it should be built into the stdlib, maybe in itertools.
thanks Paul.
itertools? that was actually the first module i checked. | | | | re: better way to write this function
On Nov 25, 11:24 pm, Paul Rudin <paul.nos...@rudin.co.ukwrote: Thanks for the link! | | | | re: better way to write this function
On Nov 26, 2007 3:24 AM, Paul Rudin <paul.nospam@rudin.co.ukwrote: Quote:
Kelie <kf9150@gmail.comwrites:
> Quote:
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!
>
See the last recipe from: http://docs.python.org/lib/itertools-recipes.html. It's not doing
quite the same thing, but gives an illustration of one way to approach
this sort of thing.
>
-- http://mail.python.org/mailman/listinfo/python-list
>
The one in the sample consumes the entire sequence up front, too. It's
trivial to write a fully generator based one (and only slightly more
work to implement an iterator that doesn't rely on generators, if you
want to avoid the slight performance hit), but there's a few subtle
issues and I too think that we really should have a good one ready for
use in itertools. Maybe I should write a patch. | | | | re: better way to write this function
On Nov 26, 1:42 am, Kelie <kf9...@gmail.comwrote: Quote:
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!
Quote: Quote: Quote:
>>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: Quote: Quote: Quote:
>>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: Quote: Quote: Quote:
>>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']] Quote: Quote: Quote:
>>chunksWithoutLeftovers(lst,2)
[['A', 'B'], ['C', 'D']]
-- Paul | | | | re: better way to write this function
On Nov 26, 7:42 am, Kelie <kf9...@gmail.comwrote: Quote:
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!
Here's a terrible way to do it:
def divide_list(lst, n):
return zip(*[lst[i::n] for i in range(n)])
[It produces a list of tuples rather than a list of lists, but it
usually won't matter].
--
Paul Hankin | | | | re: better way to write this function
Peter Otten wrote: Quote: Quote: Quote:
>>>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 | | | | re: better way to write this function
On Nov 26, 8:19 am, Peter Otten <__pete...@web.dewrote:
[...] Quote:
>
Or build a generator that works with arbitrary iterables:
> Quote: Quote:
>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 | | | | re: better way to write this function
Peter Otten wrote: Quote:
Kelie wrote:
> Quote:
>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:
> Quote: Quote:
>>>def chunks(items, n):
... return [items[start:start+n] for n in range(0, len(items)-n+1, n)]
... Quote: Quote:
>>>for i in range(1,10):
... print chunks(range(5), i)
...
[[0], [1], [2], [3], [4]]
[[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)] | | | | re: better way to write this function
Ricardo Aráoz wrote: Quote:
Peter Otten wrote:
Quote: Quote:
>You can use slicing:
>> Quote:
>>>>def chunks(items, n):
>... return [items[start:start+n] for n in range(0, len(items)-n+1, n)]
>... Quote:
>>>>for i in range(1,10):
>... print chunks(range(5), i)
>...
>[[0], [1], [2], [3], [4]]
>[[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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,501 network members.
|