CodingFrog
CodingFrog

Reputation: 1665

How to merge 1D & 2D tuples in Python?

How to merge 1D & 2D tuples in Python?

So given two lists

heights = (   165,     152,     145,    174)
pos_2D  = ( (2,3), (32,52), (73,11), (43,97) )

I would like to so something like

pos_3D = merge(heights, pos_2D)

where

pos_3D = ( (2,3,165), (32,52,152), (73,11,145), (43,97,174) )

Whats the pythonic way to do this?

Upvotes: 0

Views: 826

Answers (3)

jkhadka
jkhadka

Reputation: 2543

with zip

zip(heights,*zip(*pos_2D))

>>>[(165, 2, 3), (152, 32, 52), (145, 73, 11), (174, 43, 97)]

or if you want tuple

tuple(zip(heights,*zip(*pos_2D)))
>>>((165, 2, 3), (152, 32, 52), (145, 73, 11), (174, 43, 97))

zip makes list of tuples out of the two arguments and zip(*_) coverts the tuples back to individual arguments (think of it like unzip).


Explanation on the code.

heights = (   165,     152,     145,    174)
pos_2D  = ( (2,3), (32,52), (73,11), (43,97) )

With second tuple pos_2D we can unzip it to individual arguments as

pos_2D_unzipped = zip(*pos_2D)
print pos_2D_unzipped
>> [(2, 32, 73, 43), (3, 52, 11, 97)]

now we can use this to zip heights and pos_2D_unzipped together to get what you want.

for that we can do something like zip(heights, pos_2D_unzipped) but that only zips first 2 elements of zip with the two long tuples of pos_2D_unzipped.

zip(heights, pos_2D_unzipped)
[(165, (2, 32, 73, 43)), (152, (3, 52, 11, 97))]

What you really need to do is : provide zip with three arguments, 1. heights, 2. first element of pos_2D_unzipped and 3. second element of pos_2D_unzipped

so you could do something like :

zip(heights, pos_2D_unzipped[0],pos_2D_unzipped[1])
>>[(165, 2, 3), (152, 32, 52), (145, 73, 11), (174, 43, 97)]

Which works! But you can do something quicker. pos_2D_unzipped is a list of two elements (which are the long tuples), it would be great if you can give each element of list directly to the zip. And this is exactly what *pos_2D_unzipped does in side the zip(__). It opens the list into individual arguments for the function.

thus, now you can do,

zip(heights, *pos_2D_unzipped)
>>[(165, 2, 3), (152, 32, 52), (145, 73, 11), (174, 43, 97)]

And even better, now you can compress the two steps of unzipping pos_2D and zipping the heights and pos_2D_unzipped into single step.

zip(heights,*zip(*pos_2D))

Upvotes: 0

Rakesh
Rakesh

Reputation: 82785

Use zip

Ex:

heights = (   165,     152,     145,    174)
pos_2D  = ( (2,3), (32,52), (73,11), (43,97) )

print(tuple(j + (i,) for i, j in zip(heights, pos_2D)) )

Output:

((2, 3, 165), (32, 52, 152), (73, 11, 145), (43, 97, 174))

Upvotes: 2

blue note
blue note

Reputation: 29089

They are not exactly 1D or 2D. The first is just a tuple of integers, and the second a tuple of tuples. So, you just iterate over them in parallel (using zip) and create a new tuple element for each pair of elements

result = tuple( (*pos, h) for pos, h in zip(pos2D, heights))

Upvotes: 0

Related Questions