【问题标题】:List intersection for multiple matching instances列出多个匹配实例的交集
【发布时间】:2019-09-12 21:59:25
【问题描述】:

我有一个算法,其功能取决于两个列表之间匹配实例(甚至重复)的数量。例如:

a = ["test", "win", "win", "bike", "bike", "bike", "gem", "nine"]
b = ["test", "win", "let", "bike", "four"]

d = set(a).intersection(b)

会给我:

{"test", "win", "bike"}

我想要的输出是:

{"test", "win", "win", "bike", "bike", "bike"}

我想我可以只利用输出列表并计算每个相交单词在list a 等中存在的次数...但这是相当多的额外步骤,我希望有一个更简单的方法来实现这个输出。

我的问题是,根据提供的示例列表,我如何才能实现所需的第二个输出:

{"test", "win", "win", "bike", "bike", "bike"}

【问题讨论】:

  • 你应该使用一个列表。使用集合的主要目的是保持每个元素的唯一记录。
  • 如果列表 b 中有 2 辆自行车怎么办?结果如何?

标签: python python-3.x list set-intersection


【解决方案1】:

您可以使用collections.Counter 获取每个不同项目的计数,并使用Counter.elements 方法生成所需的列表,其中项目在通过b 中的成员资格过滤后根据计数重复(转换b到一组有效的成员查找):

from collections import Counter
set_b = set(b)
print(list(Counter({k: c for k, c in Counter(a).items() if k in set_b}).elements()))

这个输出:

['test', 'win', 'win', 'bike', 'bike', 'bike']

【讨论】:

    【解决方案2】:

    你应该使用一个列表而不是一个集合,你可以利用你已经定义的代码,所以:

    a = ["test", "win", "win", "bike", "bike", "bike", "gem", "nine"]
    b = ["test", "win", "let", "bike", "four"]
    
    s = set(a).intersection(b)
    
    output = []
    
    for e in s:
        n = max(a.count(e), b.count(e))
        output.extend([e] * n)
    
    >>> output
    ['win', 'win', 'bike', 'bike', 'bike', 'test']
    

    基本上,您所做的是重复常见元素,考虑到它在哪个列表中重复次数最多。

    【讨论】:

    • 这对于像上面这样的小列表很好,但是当输入大小增加时会变得很慢。
    猜你喜欢
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 2018-11-02
    • 2021-10-11
    • 2012-03-22
    • 1970-01-01
    相关资源
    最近更新 更多