【问题标题】:Can I reverse a Counter into a list of lists without multiples?我可以将计数器反转为没有倍数的列表列表吗?
【发布时间】:2017-05-21 17:05:55
【问题描述】:

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

什么成语可以将 Collections Counter 分配到一个列表列表中,其中每个倍数在每个列表中只出现一次?

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

【问题讨论】:

  • 最终列表中的顺序重要还是内容重要?
  • Collections Counter 返回一个dict,所以我相信我们在这一点上不走运。尽管如此,这也是一个很好的问题 - 获取两个具有倍数的列表并返回一个列表列表,每个列表没有倍数。

标签: python sorting counter


【解决方案1】:

不知道您是否在寻找单线,但这里是单线:

代码:

[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() 会将列表放在一起,并用 none 填充较短的列表

测试代码:

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']]

【讨论】:

    【解决方案2】:

    你可以试试这个:

    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。

    【讨论】:

    • 注意,在 Python 3.5 中 izip_longest() 现在是 zip_longest()
    猜你喜欢
    • 1970-01-01
    • 2013-02-16
    • 2017-09-03
    • 1970-01-01
    • 2012-02-07
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多