Is it possible to flip a counter into a list of lists without multiples?

Using the Collection Counter ,

l1 = ['a', 'b', 'b', 'c', 'c', 'b', 'e']
l2 = ['a', 'b', 'b', 'c', 'c', 'b','d']

from collections import Counter

c1 = Counter(l1)
c2 = Counter(l2)

# Intersection 
c1 & c2

>>> Counter({'b': 3, 'c': 2, 'a': 1})

      

What idiom could propagate a collection counter into a list of lists where each multiple appears only once in each list?

[['a', 'b', 'c'],['b', 'c'],['b']]

      

+3


source to share


2 answers


Don't know if you were looking for one-liner, but here's a one-liner:

Code:

[sorted(y for y in z if y is not None) 
       for z in it.izip_longest(*[[k] * l for k, l in c.items()])]

      

How?

Two key points:



  • [k] * l

    gives a list of counters whose length is equal to the value of the counter.
  • izip_longest()

    will put lists togther and pad fill to none for shorter lists

Test code:

from collections import Counter
c = Counter({'b': 3, 'c': 2, 'a': 1})

import itertools as it
print([sorted(y for y in z if y is not None) 
       for z in it.izip_longest(*[[k] * l for k, l in c.items()])])

      

Results:

[['a', 'b', 'c'], ['b', 'c'], ['b']]

      

+7


source


You can try this:

import itertools

the_dict = {'b': 3, 'c': 2, 'a': 1}

the_frequencies  = [[a]*b for a, b in the_dict.items()]

the_list = itertools.izip_longest(the_frequencies)

the_final = map(list, list(itertools.izip_longest(*the_frequencies)))

print [[i for i in b if i != None] for b in the_final]

      



This solution uses itertools for the zip lists contained in the_frequencies, which are generated by multiplying the key list multiplied by the corresponding value. Then izip builds a list with strings of elements in parameters, keeping None if the current iteration count is greater than the length of any list in the list of lists.

0


source







All Articles