RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 590198
Accepted
Bernard
Bernard
Asked:2020-11-13 00:24:31 +0000 UTC2020-11-13 00:24:31 +0000 UTC 2020-11-13 00:24:31 +0000 UTC

比较两个列表以找到符合规则的元素

  • 772

问题是,例如我有两个列表:

lst1 = ['1', '2' , '3' , '4']
lst2 = ['123', '234' , '345' , '334']

如何在第二个列表中找到仅包含第一个列表中的那些元素的此类元素,但如果第一个列表中有一个单元,则例如第二个列表中的元素“112”不适合。

也就是说,程序的结果应该是

ls3 = ['123', '234']

'345' - 不匹配,因为有一个元素“5”不在第一个列表中

'334' - 不匹配,因为有两个“3”元素,而在第一个列表中只有一个“3”元素

python
  • 5 5 个回答
  • 10 Views

5 个回答

  • Voted
  1. Timofei Bondarev
    2020-11-13T02:21:01Z2020-11-13T02:21:01Z

    这个问题可以通过使用标准的 multiset 类来解决Counter:

    from collections import Counter
    
    lst1 = ['1', '2' , '3' , '4']
    lst2 = ['123', '234' , '345' , '334']
    
    base = Counter(lst1)
    result = [s for s in lst2 if not (Counter(s) - base)]
    

    条件not (Counter(s) - base)检查s多重集中的元素不多于base

    • 10
  2. Best Answer
    jfs
    2020-11-15T08:30:38Z2020-11-15T08:30:38Z

    如果知道如何确定是否有可能使用每个字符以不超过其重复次数(谓词已知)来组成word给定字符的字符串,那么问题就简化为:charschars can_build(word, chars)

    result = list(filter(can_build, lst2))
    

    或更具可读性:

    result = [word for word in lst2 if can_build(word)]
    

    can_build里面使用的地方chars = lst1。

    如果要求使用所有的字符chars,那么就是测试它是否是word一个变位词chars,例如:“enlightener”可以通过重新排列字母“patience”得到。当完全相等被“不再”取代时,您可以使用类似的解决方案。

    can_build()可以通过查找多重集是否是word 多重集的子集来实现chars。chars如果和中的所有字符word都是唯一的,则

    can_build = set("1234").issuperset
    

    collections.Counter实现了元素可以重复的集合的思想,即multiset。如@Timofey Bondarev的回答中的优雅解决方案所示,此集合可用于实现can_build:

    can_build = lambda word, chars=Counter(lst1): not (Counter(word) - chars)
    

    可以在不使用的情况下手动实现相同的算法collections.Counter。

    from collections import defaultdict
    
    def Counter(letters):
        counts = defaultdict(int)
        for letter in letters:
            counts[letter] += 1
        return counts
    
    chars_count = Counter(chars)
    
    def can_build(word):
        return all(chars_count[char] >= count for char, count in Counter(word).items())
    

    如果所有字符都属于某个字母表,则可以使用简单列表,因为它chars始终相同,所以可以缓存chars.count这些值。例如,ifchars只能包含数字0-9:

    from string import digits
    
    chars_count = [(digit, chars.count(digit)) for digit in digits]
    
    def can_build(word):
        return all(word.count(digit) <= count for digit, count in chars_count)
    

    是O(N * M)解决方案(M=len(digits)-alphabet 大小),与O(N)使用Counter(). 如果字母表不固定:alphabet = set(word),则它是一个O(N**2)(二次)算法。如果alphabet像示例中那样固定,那么这是一个O(N)(线性)解决方案。对于小字母表,例如布尔数字 ( alphabet=(0,1)) 或 DNA 字符串 ( alphabet="GTAC"),此解决方案甚至可能比使用 的解决方案更快Counter()。

    另一个应用示例:如果word,chars这些是由其质因数表示的数字(例如:(2,2,3)表示12,(5,7)表示35),则它can_build()回答是否是word除数的问题chars,即是否为真:chars % word == 0。

    问:如何实现代码,如果你摆脱了元素必须重复多次的条件,就像它在第一个列表中一样???

    这个假设中的答案已经有效。否则,字谜就是这种情况:重复次数相同。Counter()c和 c解决方案<=不>=要求元素重复“与第一个列表中的次数一样多”(尽可能少)。

    如果你的意思是重复次数根本不重要,而只对元素是否存在感兴趣,那么情况类似于所有元素都唯一的情况,即:

    can_build = set(lst1).issuperset
    

    正如上面已经提到的。

    • 7
  3. vadim vaduxa
    2020-11-13T20:01:43Z2020-11-13T20:01:43Z
    [l2 for l2 in lst2 if all(l2.count(l) <= lst1.count(l) for l in set(l2))]
    
    • 5
  4. dio4
    2020-11-16T17:03:09Z2020-11-16T17:03:09Z
    #!/usr/bin/env python3.4
    # -*- coding: utf-8 -*-
    lst1 = ['1', '2' , '3' , '4']
    lst2 = ['123', '234' , '345' , '334']
    S1 = set(lst1)
    S2 = set(lst2)
    S3 = set()
    for x in S2:
        if set(x) <= S1: S3.add(x)
    lst3 = list(S3)
    for x in lst3:
        for y in x:
            if x.count(y) > 1:
                count = lst3.index(x)
                continue
    lst3.pop(count)
    print(lst3)
    

    如果单纯按照事物的逻辑,没有什么特别的智慧。对集合(从学校学到的)、循环和列表有一点了解。回答 ['123', '234']

    • 2
  5. Мистер Фикс
    2020-11-13T10:30:09Z2020-11-13T10:30:09Z

    上面的解决方案当然更短,但从人的角度来说,您可以这样做:

    список = ['1', '2', '3', '4']
    список2 = ['123', '234', '345', '34']
    
    результат = []
    for сочетание in список2:
        временный_список = список[:]  # копия списка
        for цифра in сочетание:
            if цифра in временный_список:
                временный_список.remove(цифра)  # чтобы не более одной проверки на число
            else:
                break
        else: результат.append(сочетание)
    
    print(результат)
    
    
    ===================== RESTART: C:\Python 3.5\задачка.py =====================
    ['123', '234', '34']
    
    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5