467,083 Members | 1,255 Online

# Packing list elements into tuples

 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 Jul 18 '05 #1
• viewed: 2438
Share:
8 Replies
 "Nickolay Kolev" wrote in message news:cm**********@f1node01.rhrz.uni-bonn.de... 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. Jul 18 '05 #2
 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 Jul 18 '05 #3
 Nickolay Kolev 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 Jul 18 '05 #4
 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 Sc***********@Acm.Org Jul 18 '05 #5
 * 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 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  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) """ Jul 18 '05 #6
 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 Jul 18 '05 #7
 "Nickolay Kolev" wrote in message news:cm**********@f1node01.rhrz.uni-bonn.de... 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. Jul 18 '05 #8
 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 Jul 18 '05 #9

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

 11 posts views Thread by Nicolas Girard | last post: by 5 posts views Thread by Christian Seberino | last post: by 9 posts views Thread by Yomanium Yoth Taripoät II | last post: by 7 posts views Thread by Ben | last post: by 3 posts views Thread by Dirk Hagemann | last post: by 90 posts views Thread by Christoph Zwerschke | last post: by 43 posts views Thread by michael.f.ellis@gmail.com | last post: by 11 posts views Thread by Noah | last post: by 17 posts views Thread by John Salerno | last post: by 6 posts views Thread by Otekpo Emmanuel | last post: by 1 post views Thread by SwissProgrammer | last post: by 2 posts views Thread by SwissProgrammer | last post: by 3 posts views Thread by SwissProgrammer | last post: by 4 posts views Thread by Ariiza13 | last post: by 2 posts views Thread by RonWesley | last post: by 5 posts views Thread by SueHopson | last post: by reply views Thread by rhonda6373 | last post: by 6 posts views Thread by Petrol | last post: by