Velocity Reviews > merge list of tuples with list

merge list of tuples with list

Daniel Wagner
Guest
Posts: n/a

 10-20-2010
Hello Everyone,

I'm new in this group and I hope it is ok to directly ask a question.

My short question: I'm searching for a nice way to merge a list of
tuples with another tuple or list. Short example:
a = [(1,2,3), (4,5,6)]
b = (7,

After the merging I would like to have an output like:
a = [(1,2,3,7), (4,5,6)]

It was possible for me to create this output using a "for i in a"
technique but I think this isn't a very nice way and there should
exist a solution using the map(), zip()-functions....

I appreciate any hints how to solve this problem efficiently.

Greetings,
Daniel Wagner

James Mills
Guest
Posts: n/a

 10-20-2010
On Wed, Oct 20, 2010 at 10:16 AM, Daniel Wagner
<(E-Mail Removed)> wrote:
> My short question: I'm searching for a nice way to merge a list of
> tuples with another tuple or list. Short example:
> a = [(1,2,3), (4,5,6)]
> b = (7,
>
> After the merging I would like to have an output like:
> a = [(1,2,3,7), (4,5,6)]

What happens with the 8 in the 2nd tuple b ?

cheers
James

--
-- James Mills
--
-- "Problems are solved by method"

Daniel Wagner
Guest
Posts: n/a

 10-20-2010
On Oct 19, 8:35*pm, James Mills <(E-Mail Removed)> wrote:
> On Wed, Oct 20, 2010 at 10:16 AM, Daniel Wagner
>
> <(E-Mail Removed)> wrote:
> > My short question: I'm searching for a nice way to merge a list of
> > tuples with another tuple or list. Short example:
> > a = [(1,2,3), (4,5,6)]
> > b = (7,

>
> > After the merging I would like to have an output like:
> > a = [(1,2,3,7), (4,5,6)]

>
> What happens with the 8 in the 2nd tuple b ?

Ohhhh, I'm sorry! This was a bad typo:
the output should look like:
a = [(1,2,3,7), (4,5,6,]

Greetings,
Daniel

Paul Rubin
Guest
Posts: n/a

 10-20-2010
Daniel Wagner <(E-Mail Removed)> writes:
>> > My short question: I'm searching for a nice way to merge a list of
>> > tuples with another tuple or list. Short example:
>> > a = [(1,2,3), (4,5,6)]
>> > b = (7, ...

> the output should look like:
> a = [(1,2,3,7), (4,5,6,]

That is not really in the spirit of tuples, which are basically supposed
to be of fixed size (like C structs). But you could write:

>>> [x+(y,) for x,y in zip(a,b)]

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

MRAB
Guest
Posts: n/a

 10-20-2010
On 20/10/2010 02:26, Paul Rubin wrote:
> Daniel Wagner<(E-Mail Removed)> writes:
>>>> My short question: I'm searching for a nice way to merge a list of
>>>> tuples with another tuple or list. Short example:
>>>> a = [(1,2,3), (4,5,6)]
>>>> b = (7, ...

>> the output should look like:
>> a = [(1,2,3,7), (4,5,6,]

>
> That is not really in the spirit of tuples, which are basically supposed
> to be of fixed size (like C structs). But you could write:
>
> >>> [x+(y,) for x,y in zip(a,b)]

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

In Python 2.x:

zip(*zip(*a) + [b])

In Python 3.x:

list(zip(*list(zip(*a)) + [b]))

Daniel Wagner
Guest
Posts: n/a

 10-20-2010
I used the following code to add a single fixed value to both tuples.
But this is still not what I want...
>>>a = [(1,2,3), (4,5,6)]
>>>b = 1
>>>a = map(tuple, map(lambda x: x + [1], map(list, a)))
>>>a

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

What I need is:
>>>a = [(1,2,3), (4,5,6)]
>>>b = (7,
>>> a = CODE
>>>a

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

Greetings,
Daniel

Daniel Wagner
Guest
Posts: n/a

 10-20-2010
SOLVED! I just found it out....

> I'm searching for a nice way to merge a list of
> tuples with another tuple or list. Short example:
> a = [(1,2,3), (4,5,6)]
> b = (7,
>
> After the merging I would like to have an output like:
> a = [(1,2,3,7), (4,5,6)]

The following code solves the problem:
>>> a = [(1,2,3), (4,5,6)]
>>> b = [7,8]
>>> a = map(tuple, map(lambda x: x + [b.pop(0)] , map(list, a)))
>>> a

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

Any more efficient ways or suggestions are still welcome!

Greetings,
Daniel

James Mills
Guest
Posts: n/a

 10-20-2010
On Wed, Oct 20, 2010 at 1:33 PM, Daniel Wagner
<(E-Mail Removed)> wrote:
> Any more efficient ways or suggestions are still welcome!

Did you not see Paul Rubin's solution:

>>> [x+(y,) for x,y in zip(a,b)]

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

I think this is much nicer and probably more efficient.

cheers
James

--
-- James Mills
--
-- "Problems are solved by method"

Chris Torek
Guest
Posts: n/a

 10-20-2010
>On Wed, Oct 20, 2010 at 1:33 PM, Daniel Wagner
><(E-Mail Removed)> wrote:
>> Any more efficient ways or suggestions are still welcome!

In article <(E-Mail Removed)>
James Mills <(E-Mail Removed)> wrote:
>Did you not see Paul Rubin's solution:
>
>>>> [x+(y,) for x,y in zip(a,b)]

> [(1, 2, 3, 7), (4, 5, 6, ]
>
>I think this is much nicer and probably more efficient.

For a slight boost in Python 2.x, use itertools.izip() to avoid
making an actual list out of zip(a,b). (In 3.x, "plain" zip() is
already an iterator rather than a list-result function.)

This method (Paul Rubin's) uses only a little extra storage, and
almost no extra when using itertools.izip() (or 3.x). I think it
is more straightforward than multi-zip-ing (e.g., zip(*zip(*a) + [b]))
as well. The two-zip method needs list()-s in 3.x as well, making
it clearer where the copies occur:

list(zip(*a)) makes the list [(1, 4), (2, 5), (3, 6)]
[input value is still referenced via "a" so
sticks around]
[b] makes the tuple (7, into the list [(7, ]
[input value is still referenced via "b" so
sticks around]
+ adds those two lists producing the list
[(1, 4), (2, 5), (3, 6), (7, ]
[the two input values are no longer referenced
list(zip(*that)) makes the list [(1, 2, 3, 7), (4, 5, 6, ]
[the input value -- the result of the addition
in the next to last step -- is no longer

All these temporary results take up space and time. The list
comprehension simply builds the final result, once.

Of course, I have not used timeit to try this out. Let's do
that, just for fun (and to let me play with timeit from the command
line):

(I am not sure why I have to give the full path to the
timeit.py source here)

sh-3.2\$ python /System/Library/Frameworks/Python.framework/\
Versions/2.5/lib/python2.5/timeit.py \
'a=[(1,2,3),(4,5,6)];b=(7,;[x+(y,) for x,y in zip(a,b)]'
100000 loops, best of 3: 2.55 usec per loop

sh-3.2\$ python [long path snipped] \
'a=[(1,2,3),(4,5,6)];b=(7,;[x+(y,) for x,y in zip(a,b)]'
100000 loops, best of 3: 2.56 usec per loop

sh-3.2\$ python [long path snipped] \
'a=[(1,2,3),(4,5,6)];b=(7,;zip(*zip(*a) + [b])'
100000 loops, best of 3: 3.84 usec per loop

sh-3.2\$ python [long path snipped] \
'a=[(1,2,3),(4,5,6)];b=(7,;zip(*zip(*a) + [b])'
100000 loops, best of 3: 3.85 usec per loop

Hence, even in 2.5 where zip makes a temporary copy of the list,
the list comprehension version is faster. Adding an explicit use
of itertools.izip does help, but not much, with these short lists:

sh-3.2\$ python ... -s 'import itertools' \
'a=[(1,2,3),(4,5,6)];b=(7,;[x+(y,) for x,y in itertools.izip(a,b)]'
100000 loops, best of 3: 2.27 usec per loop

sh-3.2\$ python ... -s 'import itertools' \
'a=[(1,2,3),(4,5,6)];b=(7,;[x+(y,) for x,y in itertools.izip(a,b)]'
100000 loops, best of 3: 2.29 usec per loop

(It is easy enough to move the assignments to a and b into the -s
argument, but it makes relatively little difference since the list
comprehension and two-zip methods both have the same setup overhead.
The "import", however, is pretty slow, so it is not good to repeat
it on every trip through the 100000 loops -- on my machine it jumps
to 3.7 usec/loop, almost as slow as the two-zip method.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html

Peter Otten
Guest
Posts: n/a

 10-20-2010
Daniel Wagner wrote:

> Hello Everyone,
>
> I'm new in this group and I hope it is ok to directly ask a question.
>
> My short question: I'm searching for a nice way to merge a list of
> tuples with another tuple or list. Short example:
> a = [(1,2,3), (4,5,6)]
> b = (7,
>
> After the merging I would like to have an output like:
> a = [(1,2,3,7), (4,5,6)]
>
> It was possible for me to create this output using a "for i in a"
> technique but I think this isn't a very nice way and there should
> exist a solution using the map(), zip()-functions....
>
> I appreciate any hints how to solve this problem efficiently.

>>> from itertools import starmap, izip
>>> a = [(1,2,3), (4,5,6)]
>>> b = (7,

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

This is likely slower than the straightforward

[x + (y,) for x, y in zip(a, b)]

for "short" lists, but should be faster for "long" lists. Of course you'd
have to time-it to be sure.
You should also take into consideration that the latter can be understood
immediately by any moderately experienced pythonista.

Peter