Reputation: 946
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
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:
a_list
, while you should iterate over indexes (I use the range of the longest sublist)x[index]
, while I use x[index:index+1]
, which returns a list instead (an empty one if index is out of range)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
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
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