Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Packing list elements into tuples

Reply
Thread Tools

Packing list elements into tuples

 
 
Nickolay Kolev
Guest
Posts: n/a
 
      11-09-2004
Hi all,

I have a list whose length is a multiple of 3. I want to get a list of
tuples each of which has 3 consecutive elements from the original list,
thus packing the list into smaller packets. Like this:

l = [1,2,3,4,5,6]

tups = [(1,2,3), (4,5,6)]

or

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

tups = [(1,2,3), (4,5,6), (7,8,9)]

if i can dictionaries it would be even better:


l = [1,2,3,4,5,6]

tups = [
{'first':1,'second':2,'third':3},
{'first':4,'second':5,'third':6}
]

and so on.

Any ideas?

Many thanks in advance!

Cheers,
-- Nickolay
 
Reply With Quote
 
 
 
 
Russell Blau
Guest
Posts: n/a
 
      11-09-2004
"Nickolay Kolev" <> wrote in message
news:cmrcqq$rv4$...
> Hi all,
>
> I have a list whose length is a multiple of 3. I want to get a list of
> tuples each of which has 3 consecutive elements from the original list,
> thus packing the list into smaller packets. Like this:
>
> l = [1,2,3,4,5,6,7,8,9]
>
> tups = [(1,2,3), (4,5,6), (7,8,9)]


How's this? :

>>> alist

[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> tups = [tuple(alist[i:i+3]) for i in xrange(0, len(alist), 3)]
>>> tups

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


>
> if i can dictionaries it would be even better:
>
>
> l = [1,2,3,4,5,6]
>
> tups = [
> {'first':1,'second':2,'third':3},
> {'first':4,'second':5,'third':6}
> ]


Well, now that you've been introduced to the concept of list indexes and
list comprehensions, I think that extending it to dictionaries is fairly
simple.


--
I don't actually read my hotmail account, but you can replace hotmail with
excite if you really want to reach me.


 
Reply With Quote
 
 
 
 
Nickolay Kolev
Guest
Posts: n/a
 
      11-09-2004
Nickolay Kolev wrote:

> Hi all,
>
> I have a list whose length is a multiple of 3. I want to get a list of
> tuples each of which has 3 consecutive elements from the original list,
> thus packing the list into smaller packets. Like this:


I found it in the cookbook:
http://aspn.activestate.com/ASPN/Coo.../Recipe/303060

It looks quite cryptic, could anyone give me some pointers at what
exactly is going on in the function?

Cheers,
-- Nickolay
 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      11-09-2004
Nickolay Kolev <nmkolev <at> uni-bonn.de> writes:
> l = [1,2,3,4,5,6]
>
> tups = [(1,2,3), (4,5,6)]


My favorite idiom:

>>> l = [1,2,3,4,5,6]
>>> zip(*(iter(l),)*3)

[(1, 2, 3), (4, 5, 6)]
>>> l = [1,2,3,4,5,6,7,8,9]
>>> zip(*(iter(l),)*3)

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

If you want dicts, try:

>>> l = [1,2,3,4,5,6]
>>> tuples = zip(*(iter(l),)*3)
>>> labels = 'first second third'.split()
>>> [dict(zip(labels, t)) for t in tuples]

[{'second': 2, 'third': 3, 'first': 1}, {'second': 5, 'third': 6, 'first': 4}]

Basically, you can make a dict with whatever labels you want by zipping your
labels with the appropriate tuples and calling the dict builtin.

Steve

 
Reply With Quote
 
Scott David Daniels
Guest
Posts: n/a
 
      11-09-2004
I kind of like:
[dict(first=lst[k], second=lst[k+1], third=lst[k+2])
for k in range(0, len(lst), 3)]

--Scott David Daniels

 
Reply With Quote
 
Thorsten Kampe
Guest
Posts: n/a
 
      11-10-2004
* Nickolay Kolev (2004-11-09 22:29 +0100)
> I have a list whose length is a multiple of 3. I want to get a list of
> tuples each of which has 3 consecutive elements from the original list,
> thus packing the list into smaller packets. Like this:
>
> l = [1,2,3,4,5,6]
>
> tups = [(1,2,3), (4,5,6)]
>
> or
>
> l = [1,2,3,4,5,6,7,8,9]
>
> tups = [(1,2,3), (4,5,6), (7,8,9)]


Fragment[1] from a general purpose partitioning utility:

def part(seq, slice):
""" partition seq """
return [seq[slice * index:slice * (index + 1)]
for index in range(len(seq) / slice + bool(len(seq) % slice))]


> if i can dictionaries it would be even better:
>
> l = [1,2,3,4,5,6]
>
> tups = [
> {'first':1,'second':2,'third':3},
> {'first':4,'second':5,'third':6}
> ]


You're losing order and therfore you're attaching 'first', 'second'
and so on because you obviously need the original order. So don't use
a dictionary.


Thorsten

[1] Just for the record:
def part(seq, slice = None, modus = None):
"""
partition seq
syntax:
part(seq, boolean_function, modus = 'bool')
-> [[first_true_items], [first_false_item, remaining_items]]
part('str', 'separator', modus = 'sep') or
part('str', ['separators'], modus = 'sep')
part(list, item, modus = 'sep')
part(n, modus = 'set')
-> len([all_possible_partitions_of_[0, 1, ..., n]])
part(list, modus = 'set'
-> [all_possible_partitions_of_list]
part(seq, int, modus = 'size')
-> [seq0, seq1, ..., seqn] - where len(seq(i)) = int
part(seq, [n0, n1, ..., n(i)], modus = 'size'
-> [seq0, seq1, ..., seq(i)] - where len(seq(i)) = n(i)
"""
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      11-10-2004
Nickolay Kolev wrote:

> I have a list whose length is a multiple of 3. I want to get a list**of
> tuples each of which has 3 consecutive elements from the original list,
> thus packing the list into smaller packets. Like this:


> ... dictionaries ... would be even better:


> l = [1,2,3,4,5,6]
>
> tups = [
> {'first':1,'second':2,'third':3},
> {'first':4,'second':5,'third':6}
> ]


itertools to the rescue:

>>> from itertools import *
>>> names = "first second third".split()
>>> items = range(6)
>>> map(dict, takewhile(bool, starmap(zip, repeat((names, iter(items))))))

[{'second': 1, 'third': 2, 'first': 0}, {'second': 4, 'third': 5, 'first':
3}]

Fun, but not recommended. There must be a simpler expression where you need
not mention len(names) explicitly - but right now I can't think of one.
Note how the nonzero len(items) % len(names) case is handled:

>>> map(dict, takewhile(bool, starmap(zip, repeat((names,

iter(range(5)))))))
[{'second': 1, 'third': 2, 'first': 0}, {'second': 4, 'first': 3}]

However, in real life I would rather go with Steven Bethard's two-step
approach...

Peter




 
Reply With Quote
 
Russell Blau
Guest
Posts: n/a
 
      11-10-2004
"Nickolay Kolev" <> wrote in message
news:cmreif$rve$...
> Nickolay Kolev wrote:
>
> I found it in the cookbook:
> http://aspn.activestate.com/ASPN/Coo.../Recipe/303060
>
> It looks quite cryptic, could anyone give me some pointers at what
> exactly is going on in the function?


The function contains only one significant line, which is:

return zip(*[lst[i::n] for i in range(n)])

To figure out what it is doing, take it one piece at a time. Start with a
list:

>>> lst

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

Pick how many elements you want in each group:

>>> n=3


Now see what the list comprehension does:

>>> [lst[i::n] for i in range(n)]

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

So this breaks up the list into three separate lists by taking each n'th
element from the original list, then combines them. The "n" in lst[i::n]
determines how many elements will be skipped in creating each sub-list.
Unfortunately, this syntax isn't mentioned in the tutorial or the library
reference; you have to dig to find an explanation of it in
http://www.python.org/doc/2.3.4/what...on-slices.html

Let's store the result of the last step so we can see what the following
step does:

>>> m = [lst[i::n] for i in range(n)]
>>> zip(*m)

[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12)]

The magic function zip() takes a list of sequences as its argument, and
returns a new list that rearranges them. Imagine the first list (m) as a
two-dimensional table in which each sub-sequence is a row; zip() goes
through the table and returns the columns as the sub-sequences. See
http://www.python.org/doc/2.3.4/lib/built-in-funcs.html (all the way at the
end).


--
I don't actually read my hotmail account, but you can replace hotmail with
excite if you really want to reach me.



 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      11-10-2004
On Wed, 10 Nov 2004 19:00:52 +0800, Deepak Sarda <> wrote:
>
> > >>> l = [1,2,3,4,5,6]
> > >>> zip(*(iter(l),)*3)

> > [(1, 2, 3), (4, 5, 6)]
> > >>> l = [1,2,3,4,5,6,7,8,9]
> > >>> zip(*(iter(l),)*3)

> > [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

>
> Can someone explain how this works?!
>

[snip]
>
> So zip() basically gets zip(iter(l), iter(l), iter(l)) , right?


Close, but note that zip(iter(l), iter(l), iter(l)) creates three
iterators to the list l, while zip(*(iter(l),)*3) uses the same
iterator at each position in the tuple.

>>> l = [1,2,3,4,5,6]
>>> zip(iter(l), iter(l), iter(l))

[(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6)]
>>> itr = iter(l)
>>> zip(itr, itr, itr)

[(1, 2, 3), (4, 5, 6)]

Here's basically what zip ends up doing when you give it 3 names bound
to the same iterator:

>>> itr = iter(l)
>>> tuple1 = (itr.next(), itr.next(), itr.next())
>>> tuple1

(1, 2, 3)
>>> tuple2 = (itr.next(), itr.next(), itr.next())
>>> tuple2

(4, 5, 6)
>>> result = [tuple1, tuple2]
>>> result

[(1, 2, 3), (4, 5, 6)]

Note that when they're not the same iterator, zip does something like:

>>> itr1, itr2, itr3 = iter(l), iter(l), iter(l)
>>> tuple1 = (itr1.next(), itr2.next(), itr3.next())
>>> tuple1

(1, 1, 1)
>>> tuple2 = (itr1.next(), itr2.next(), itr3.next())
>>> tuple2

(2, 2, 2)
....

So you just get 3 copies of the elements at each index in your list.

Hope that helped!

Steve
--
You can wordify anything if you just verb it.
- Bucky Katt, Get Fuzzy
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dictionaries with tuples or tuples of tuples Jon Reyes Python 18 02-19-2013 03:56 AM
Passing tuples of tuples to sqlite xera121 Python 8 09-30-2009 05:45 AM
tuples within tuples korovev76@gmail.com Python 12 10-27-2007 08:16 PM
Different tuples to one container? (One type of a pointer to point to different kinds of tuples?) fff_afafaf@yahoo.com C++ 5 10-05-2006 11:17 PM
Combine two dictionaries into a list of 3-tuples Nickolay Kolev Python 3 11-10-2004 09:25 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57