slice iterator?

R

Ross

I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists? If the above
problem were to be split into groups of 3, I've tried something like:

start = 0
stop = 3
for i in range(len(a)):
segment = a[start:stop]
print segment
start += stop
stop += stop

Unfortunately start and stop don't increment using this code. Ideally,
my outcome would be
[1,2,3]
[4,5,6]
[7,8,9]
[10,11,12]
 
P

Paul Rubin

Ross said:
I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists?

That question comes up so often it should probably be a standard
library function.

Anyway, here is an iterator, if that's what you want:
>>> from itertools import islice
>>> a = range(12)
>>> xs = iter(lambda x=iter(a): list(islice(x,3)), [])
>>> print list(xs)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

Of course, as the saying goes, there's more than one way to do it ;-)
 
J

John O'Hagan

lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists? If the above
problem were to be split into groups of 3, I've tried something like:

start = 0
stop = 3
for i in range(len(a)):
    segment = a[start:stop]
    print segment
    start += stop
    stop += stop

This doesn't work because you're looping over every element in your list
(instead of every slice) and because you're incrementing the increment by
using "stop" for two different things (endpoint and increment).

This seems to work:
... segment = a[3 * i:3 * (i + 1)]
... print segment

Regards,

john
 
J

John O'Hagan

lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists? If the above
problem were to be split into groups of 3, I've tried something like:
[..]

This seems to work:
... segment = a[3 * i:3 * (i + 1)]
... print segment
[...]

But if len(a) is not divisible by the increment, that misses the last (short)
slice, so using the step argument to range:
.... segment = a[i:i + 3]
.... print segment

is better. Or as a list comprehension:

[a[i:i + 3] for i in range (0, len(a), 3)]


HTH,

John
 
N

Ned Deily

Ross said:
I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists?

That question comes up so often it should probably be a standard
library function.

Anyway, here is an iterator, if that's what you want:
from itertools import islice
a = range(12)
xs = iter(lambda x=iter(a): list(islice(x,3)), [])
print list(xs)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
Of course, as the saying goes, there's more than one way to do it ;-)

python2.6 itertools introduces the izip_longest function and the grouper
recipe <http://docs.python.org/library/itertools.html>:

def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
 
P

Paul McGuire

Ross said:
I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists?
That question comes up so often it should probably be a standard
library function.
Anyway, here is an iterator, if that's what you want:
   >>> from itertools import islice
   >>> a = range(12)
   >>> xs = iter(lambda x=iter(a): list(islice(x,3)), [])
   >>> print list(xs)
   [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
Of course, as the saying goes, there's more than one way to do it ;-)

python2.6 itertools introduces the izip_longest function and the grouper
recipe <http://docs.python.org/library/itertools.html>:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

--
 Ned Deily,
 (e-mail address removed)- Hide quoted text -

- Show quoted text -

Here's a version that works pre-2.6:
grouper = lambda iterable,size,fill=None : zip(*[(iterable+[fill,]*(size-1))[i::size] for i in range(size)])
a = range(12)
grouper(a,6) [(0, 1, 2, 3, 4, 5), (6, 7, 8, 9, 10, 11)]
grouper(a,5) [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, None, None, None)]
grouper(a,3)
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]

-- Paul
 
R

ryles

I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists? If the above
problem were to be split into groups of 3, I've tried something like:

start = 0
stop = 3
for i in range(len(a)):
    segment = a[start:stop]
    print segment
    start += stop
    stop += stop

Unfortunately start and stop don't increment using this code. Ideally,
my outcome would be
[1,2,3]
[4,5,6]
[7,8,9]
[10,11,12]

There is also an iterator version here:
http://code.activestate.com/recipes/303279
 
E

Emile van Sebille

On 5/8/2009 8:17 PM Ross said...
I have a really long list that I would like segmented into smaller
lists. Let's say I had a list a = [1,2,3,4,5,6,7,8,9,10,11,12] and I
wanted to split it into groups of 2 or groups of 3 or 4, etc. Is there
a way to do this without explicitly defining new lists?
>>> a = [1,2,3,4,5,6,7,8,9,10,11,12]
>>>
>>> for k in [2,3,4,5,6]:
.... print [ a[j:j+k] for j in range(0,len(a),k) ]
....
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]

The point is of course to use the form a[j:j+k] which doesn't create new
lists.

Emile
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top