2

I'm facing a problem involving lists. I have a nested list like:

A = [ [0,2,3,4], [0,1,1,2] ]

where the first list holds the the y and the second list holds the x coordinate for four different points. I'd like to obtain a list:

B = [[0,0], [1,2], [1,3], [2,4]]

where each list represents a point. Is there a simple pythonic way to do that or must I deal with for loops? Thank you in advance and sorry if a similar question has been already posted.

timgeb
  • 76,762
  • 20
  • 123
  • 145
urgeo
  • 645
  • 1
  • 9
  • 19

3 Answers3

3

That's what the zip function is for.

>>> A = [ [0,2,3,4], [0,1,1,2] ]
>>> B = [list(x) for x in zip(*A[::-1])]
>>> B
[[0, 0], [1, 2], [1, 3], [2, 4]]

if you don't need your elements to be lists (i.e. tuples are fine, too), this shortens to

>>> zip(*A[::-1])
[(0, 0), (1, 2), (1, 3), (2, 4)]

in Python 2 and

>>> list(zip(*A[::-1]))
[(0, 0), (1, 2), (1, 3), (2, 4)]

in Python 3.

Explanation of the syntax:

A[::-1] is reversing A:

>>> A[::-1]
[[0, 1, 1, 2], [0, 2, 3, 4]]

The reversed list is then passed in an unpacked form (notice the *) to the zip function, which is equivalent to

>>> zip([0, 1, 1, 2], [0, 2, 3, 4])
[(0, 0), (1, 2), (1, 3), (2, 4)]

and zip will build tuples from the first, second, ..., n'th elements from each iterable.

edit:

Minor improvement:

>>> zip(*reversed(A))
[(0, 0), (1, 2), (1, 3), (2, 4)]

should be more memory efficient because reversed gives you an iterator, A[::-1] gives you a complete list, which we don't really need.

timgeb
  • 76,762
  • 20
  • 123
  • 145
1

A couple things. First, those are Python lists which roughly correspond to ArrayLists in other programming languages. Second you asked for tuple elements in the result, but the code you posted has elements of type list.

Use the zip builtin function.

B = list(zip(*A[::-1]))

print(B)

yields

[(0, 0), (2, 1), (3, 1), (4, 2)]

If you want elements of type list, you can do the following.

B = list(map(list, zip(*A[::-1])))

print(B)

yields

[[0, 0], [2, 1], [3, 1], [4, 2]]
Alex
  • 18,484
  • 8
  • 60
  • 80
1

numpy can do it also, in a perhaps more readable way:

In [88]: y,x=A;numpy.transpose([x,y]).tolist()
Out[88]: [[0, 0], [1, 2], [1, 3], [2, 4]]
B. M.
  • 18,243
  • 2
  • 35
  • 54