简体   繁体   中英

change list of tuples to 2 lists - Python

I have a list of tuples (in this case its coordinates for latitude and longitude)

[(51.69768233153901, -5.039923897568534),
(52.14847612092221, 0.33689512047881015),
(52.14847612092221, 0.33689512047881015),
....]

I am trying to get them into 2 separate lists (one for latitude and one for longitude)

I cannot work out how to loop through to add them to the lists, so far I have:

lat = latlon_df.at[0,'LatLon'][0] 
lon = latlon_df.at[0,'LatLon'][1]

which identifies the first of each. Could someone show me how do create the 2 new lists?

Thanks for your help!

Try this:

coords = [(51.69768233153901, -5.039923897568534),
          (52.14847612092221, 0.33689512047881015),
          (52.14847612092221, 0.33689512047881015)]

lat, lon = map(list, zip(*coords))

Adapted from this answer here Transpose/Unzip Function (inverse of zip)?

If I make a list of tuples with a list comprehension like:

In [131]: ll = [(i,j) for i,j in zip(range(10),range(5,15))]
In [132]: ll
Out[132]: 
[(0, 5),
 (1, 6),
 (2, 7),
 (3, 8),
 (4, 9),
 (5, 10),
 (6, 11),
 (7, 12),
 (8, 13),
 (9, 14)]

I can easily split it into 2 list with 2 list comprehensions:

In [133]: [i[0] for i in ll], [i[1] for i in ll]
Out[133]: ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

Yes, it involves looping over ll twice, but I'd end up looping over it many more times if tried to work out a way of doing it just one loop. Sometimes the simple straightforward approach is better.

Having said that, there is a list version of transpose that does the job

In [134]: list(zip(*ll))
Out[134]: [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), (5, 6, 7, 8, 9, 10, 11, 12, 13, 14)]

This gives a list of 2 tuples, each with a 'column' of the original. My original constructor can be simplified to

list(zip(range(10),range(5,15)))

So the list(zip(*... flips the list back and forth.

But:

lat = latlon_df.at[0,'LatLon'][0]

suggests that the list of tuples might actually be a pandas dataframe. pandas probably has its own tools for indexing in this way. You previously asked about this in dataframe terms

Removing round brackets from a dataframe of lat/lon pairs

If the list was really a structured array:

In [143]: arr=np.array(ll, dtype='i,i')

The print display looks a lot like a list of tuples (though missing some ,)

In [144]: print(arr)
[(0, 5) (1, 6) (2, 7) (3, 8) (4, 9) (5, 10) (6, 11) (7, 12) (8, 13) (9, 14)]
In [145]: arr
Out[145]: 
array([(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11), (7, 12),
       (8, 13), (9, 14)], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])

It is easy to select 'fields' by name:

In [146]: arr['f0']
Out[146]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
In [147]: arr['f1']
Out[147]: array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14], dtype=int32)

Using list comprehension:

lats, lons = [[coord[index] for coord in coords] for index in (0,1)]

Note that using list comprehension is over a half order of magnitude faster than the map-list-zip approach for large coordinate lists:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM