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 to share
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 to share