sptramp
sptramp

Reputation: 946

How do I get elements on different size lists inside another list?

How do I get all elements inside of different sizes sublists?

I have sublists inside of a_list:

a_list = [['a', 'b'], ['a', 'b'], ['a']]

I need to group all elements according to their indexes and I need it to ignore if a sublist is missing an element.

This is the output I need:

['a', 'a', 'a']
['b', 'b'] # here's where I'm having problems

I have tried:

for index, a in enumerate(a_list):
   another_list = (list(zip(*a_list))[index]) # IndexError

Also tried:

another_list = list()
for index, a in enumerate(a_list):      
  another_list.append([x[index] for x in a_list])  # IndexError

Upvotes: 0

Views: 55

Answers (3)

Lante Dellarovere
Lante Dellarovere

Reputation: 1858

This should work:

a_list = [['a', 'b'], ['a', 'b'], ['a']]

r = len(max(a_list, key=len))
z = [sum([x[i:i+1] for x in a_list], []) for i in range(r)]
z
>>> [['a', 'a', 'a'], ['b', 'b']]

Explanation:

Let's consider your second attempt:

another_list = list()
for index, a in enumerate(a_list):      
  another_list.append([x[index] for x in a_list])  # IndexError

The problem with this code is:

  1. you are iterating over a_list, while you should iterate over indexes (I use the range of the longest sublist)
  2. you get IndexError because you access the sublist element by x[index], while I use x[index:index+1], which returns a list instead (an empty one if index is out of range)
  3. I use sum(index_group, []) in order to flatten the group (see code below)

In my code I then merged all this in a list comprehension, but below can find an equivalent version using a for loop as you did.

Modified version of your code:

a_list = [['a', 'b'], ['a', 'b'], ['a']]
another_list = list()
for index in range(max([len(x) for x in a_list])):  # loop over indexes
    # create a list of sublist slices containing the index-th element
    ind_group = [x[index:index+1] for x in a_list]
    # flatten the list
    flat_ind_group = sum(ind_group, [])
    another_list.append(flat_ind_group)
another_list

>>> [['a', 'a', 'a'], ['b', 'b']]

Upvotes: 2

Sheldore
Sheldore

Reputation: 39042

You can first flatten your list and then use Counter module to count the frequencies

from collections import Counter

a_list = [['a', 'b'], ['a', 'b'], ['a']]
a_list_flat = [i for sub in a_list for i in sub]

another_list = [[k for _ in range(v)] for k, v in Counter(a_list_flat).items()]
# [['a', 'a', 'a'], ['b', 'b']]

Alternatively,

another_list = [[k]*v for k, v in Counter(a_list_flat).items()] 

Upvotes: 1

Austin
Austin

Reputation: 26039

You need zip_longest with fillvalue handling the empty case + a chain.from_iterable for flattening lists.

[list(chain.from_iterable(x)) for x in zip_longest(*a_list, fillvalue='')]

Code:

from itertools import chain, zip_longest

a_list = [['a', 'b'], ['a', 'b'], ['a']]

print([list(chain.from_iterable(x)) for x in zip_longest(*a_list, fillvalue='')])
# [['a', 'a', 'a'], ['b', 'b']]

Upvotes: 2

Related Questions