简体   繁体   中英

Python: transform a list of lists of tuples

Suppose I have a data structure as follows:

[[ tuple11,
   tuple12,
   ... ],
 [ tuple21,
   tuple22,
   ... ],
 ...]

That is, the outer list can have any number of elements and each element (list) can contain any number of elements (tuples). How can I transform it to:

[[ tuple11,
   tuple21,
   ... ],
 [ tuple12,
   tuple22,
   ... ],
 ... ]

I have the following solution working for two elements in the outer list, but I cannot figure out how to generalise it:

map(lambda x, y: [x, y], *the_list)

Added:

Just to add some more detail, each of the tuples above is in fact a tuple of two np.array s.

If I start out with the following data structure:

[[(array([111, 111]), array([121, 121])),
  (array([112, 112]), array([122, 122])),
  (array([131, 131]), array([141, 141])),
  (array([132, 132]), array([142, 142]))],
 [(array([211, 211]), array([221, 221])),
  (array([212, 212]), array([222, 222])),
  (array([231, 231]), array([241, 241])),
  (array([232, 232]), array([242, 242]))]]

I need to turn this into:

[[(array([111, 111]), array([121, 121])),
  (array([211, 211]), array([221, 221]))],
 [(array([112, 112]), array([122, 122])),
  (array([212, 212]), array([222, 222]))],
 [(array([131, 131]), array([141, 141])),
  (array([231, 231]), array([241, 241]))],
 [(array([132, 132]), array([142, 142])),
  (array([232, 232]), array([242, 242]))]]

Note that the arrays are not always 1✕2 but 1✕N in general for any positive N. There are always two arrays in each tuple but any number of tuples in each inner list and any number of these inner lists in the outer list.

I am quite used to juggling NumPy arrays, but I have very little experience with the native lists, tuples etc.

You want the columns, so you can use zip function :

zip(*main_list)

But since it returns the columns in tuple format if you only want list you can use map to convert them to list :

map(list,zip(*main_list))

Demo:

>>> main_list=[[(1,2),(3,4)],[(5,6),(7,8)]]
>>> zip(*main_list)
[((1, 2), (5, 6)), ((3, 4), (7, 8))]

And with your example :

>>> main_list=[[(np.array([111, 111]), np.array([121, 121])),
...   (np.array([112, 112]), np.array([122, 122])),
...   (np.array([131, 131]), np.array([141, 141])),
...   (np.array([132, 132]), np.array([142, 142]))],
...  [(np.array([211, 211]), np.array([221, 221])),
...   (np.array([212, 212]), np.array([222, 222])),
...   (np.array([231, 231]), np.array([241, 241])),
...   (np.array([232, 232]), np.array([242, 242]))]]
>>> 
>>> zip(*main_list)
[((array([111, 111]), array([121, 121])), (array([211, 211]), array([221, 221]))), 
((array([112, 112]), array([122, 122])), (array([212, 212]), array([222, 222]))), 
((array([131, 131]), array([141, 141])), (array([231, 231]), array([241, 241]))), 
((array([132, 132]), array([142, 142])), (array([232, 232]), array([242, 242])))]

I seem to have found a solution. I don't consider it elegant but at least it seems to work. Let's call the original list of lists of tuples main_list and the transformed list of lists of tuples new_list :

def transform_coeff_struct(main_list):

    new_list = []
    for ii, inner_list in enumerate(main_list):
        for jj, some_tuple in enumerate(inner_list):
            if ii==0:
                new_list.append([some_tuple,])
            else:
                new_list[jj].append(some_tuple)
    return new_list

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