简体   繁体   中英

How to achieve two separate list of lists from a single list of lists of tuple with list comprehension?

Say, I have a two 2D list like below:

[[('a', '1'), ('a', '12'), ('a', '3')], [('b', '21'), ('b', '31')], [ ('c', '11')]]

The output I want to achieve is:

Output_list=[['1','12','3'], ['21','31'], ['11']]

The main complexity here is I want to achieve the output through a single list comprehension .

One of my attempts was:

print [a for innerList in fin_list1 for a,b in innerList]

Output:

['1', '12', '3', '21', '31', '11']

But, as you can see, though I have successfully retrieve the second elements of each tuple, i failed to retain my inner list structure.

We start with this:

>>> l = [[('a', '1'), ('a', '12'), ('a', '3')], [('b', '21'), ('b', '31')], [ ('c', '11')]]

Initially you tried to do something along these lines:

>>> [y for sublist in l for x, y in sublist]
['1', '12', '3', '21', '31', '11']

The mistake here is that this list comprehension is one-dimensional, ie all the values will be just integers instead of lists themselves

In order to make this two-dimensional, our values need to be lists. The easiest way to do this is by having our value expression be a nested list comprehension that iterates over the elements of the sublists of the original list:

>>> [[y for x, y in sublist] for sublist in l]
[['1', '12', '3'], ['21', '31'], ['11']]

Technically this is two list comprehensions, but obviously a list comprehension can be replaced by map as explained in Roberto's answer.

First, let's assign the data:

>>> data = [
  [('a', '1'), ('a', '12'), ('a', '3')],
  [('b', '21'), ('b', '31')],
  [('c', '11')],
]

You can use itemgetter to create a function that gets one element from the tuple:

>>> from operator import itemgetter
>>> first = itemgetter(0)
>>> second = itemgetter(1)

Now you can transform inner lists by using map :

>>> [map(first, row) for row in data]
[['a', 'a', 'a'], ['b', 'b'], ['c']]
>>> [map(second, row) for row in data]
[['1', '12', '3'], ['21', '31'], ['11']]

You could also create first and second without using itemgetter :

def first(xs):
    return xs[0]

def second(xs):
    return xs[1]
the_list = [[('a', '1'), ('a', '12'), ('a', '3')], [('b', '21'), ('b', '31')], [ ('c', '11')]]

new_list = [[x[1] for x in y] for y in the_list]

print new_list

Output:

[['1', '12', '3'], ['21', '31'], ['11']]

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