我可以将计数器转换为没有倍数的列表列表吗?

时间:2017-05-21 17:05:55

标签: python sorting counter

使用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})

什么成语可以将收集计数器分配到列表列表中,每个列表在每个列表中只出现一次?

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

2 个答案:

答案 0 :(得分:7)

不知道你是否正在寻找单线,但这是一个单线:

<强>代码:

[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()])]

如何吗

这里有两个关键的事情:

  1. [k] * l给出一个计数器键列表,它是计数器值长
  2. izip_longest()会将列表添加到其他内容中,填充填充时不会显示更短的列表
  3. 测试代码:

    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()])])
    

    <强>结果:

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

答案 1 :(得分:0)

你可以试试这个:

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]

此解决方案使用itertools压缩the_frequencies中包含的列表,这些列表是通过将密钥列表乘以其对应值而创建的。然后,izip与the_frequencies中的元素行形成一个列表,如果当前迭代的计数大于列表列表中任何列表的长度,则存储None。