是否有方法验证一个列表中的每一项是否至少存在于另一个列表中一次?

2024-10-02 00:40:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试验证列表中的每个字符串在另一个列表中是否至少存在一次。我经常遇到的问题是字符串永远不会完全匹配,所以我需要某种形式的regex/globbing。你知道吗

must_have_list = ['APPLE SSD', 'APPLE HDD']
example_device_list = [u'APPLE SSD SM128E', u'APPLE HDD HTS541010A9E662']
example_device_list2 = [u'APPLE SSD SD0128F', u'APPLE HDD ST3000DM001']

如果给定的设备列表至少包含来自must_have_list的每个设备字符串中的一个,则返回True。如果给定的设备列表只包含must_have_list中的一个(或没有)项,则返回False

[u'APPLE SSD SM128E', u'APPLE HDD HTS541010A9E662'] 

True找到每个

[u'APPLE HDD HTS541010A9E662', u'APPLE HDD HTS541010A9E662']

False仅找到2xAPPLE HDD,未列出APPLE SSD

[u'APPLE HDD HTS541010A9E662', u'APPLE HDD HTS541010A9E662', u'APPLE SSD SM128E']

True每个都找到一个,即使有多个APPLE HDD

[u'APPLE SSD SM128E']

False仅列出APPLE SSD,未列出APPLE HDD

如何使用regex验证一个列表中的每个项目是否存在于另一个列表中?你知道吗


Tags: 字符串falsetrueapple列表exampledevicehave
3条回答

不使用regex。这是一种使用str.startswith()解决问题的方法:

def check (a=list, b=list):
    checked = []
    for k in a:
        c = False
        for j in b:
            if j.startswith(k):
                c = True
                break
        checked.append(c)
    return all(checked)

# inputs
must_have_list = ['APPLE SSD', 'APPLE HDD']
example_device_list = ['APPLE SSD SM128E', 'APPLE HDD HTS541010A9E662']
example_device_list2 = ['APPLE SSD SD0128F', 'APPLE HDD ST3000DM001']
example_device_list3 = ['APPLE ASD SD0128F', 'APPLE HDD ST3000DM001']
example_device_list4 = ['APPLE SSD SD0128F', 'APPLE ADD ST3000DM001']
example_device_list5 = ['APPLE HDD HTS541010A9E662', 'APPLE HDD HTS541010A9E662', 'APPLE SSD SM128E']

# Some tests with this lists
check_list = check(must_have_list, example_device_list)
check_list2 = check(must_have_list, example_device_list2)
check_list3 = check(must_have_list, example_device_list3)
check_list4 = check(must_have_list, example_device_list4)
check_list5 = check(must_have_list, example_device_list5)

# Outputs
print "All items of %s exists at least once in %s: %r" % ("must_have_list", "example_device_list", check_list)
print "All items of %s exists at least once in %s: %r" % ("must_have_list", "example_device_list2", check_list2)
print "All items of %s exists at least once in %s: %r" % ("must_have_list", "example_device_list3", check_list3)
print "All items of %s exists at least once in %s: %r" % ("must_have_list", "example_device_list4", check_list4)
print "All items of %s exists at least once in %s: %r" % ("must_have_list", "example_device_list5", check_list5)

输出:

All items of must_have_list exists at least once in example_device_list: True
All items of must_have_list exists at least once in example_device_list2: True
All items of must_have_list exists at least once in example_device_list3: False
All items of must_have_list exists at least once in example_device_list4: False
All items of must_have_list exists at least once in example_device_list5: True

您可以使用allany来测试您的条件:

must_have_list = ['APPLE SSD', 'APPLE HDD']
examples=[[u'APPLE SSD SM128E', u'APPLE HDD HTS541010A9E662'],
          [u'APPLE SSD SD0128F', u'APPLE HDD ST3000DM001'],
          [u'APPLE HDD HTS541010A9E662', u'APPLE HDD HTS541010A9E662', u'APPLE SSD SM128E'],
          [u'APPLE SSD SM128E'],
          [u'APPLE SSD SM128E',u'APPLE SSD SM128E']]

for ex in examples:
    print ex, all(any(r in s for s in ex) for r in must_have_list)

印刷品:

[u'APPLE SSD SM128E', u'APPLE HDD HTS541010A9E662'] True
[u'APPLE SSD SD0128F', u'APPLE HDD ST3000DM001'] True
[u'APPLE HDD HTS541010A9E662', u'APPLE HDD HTS541010A9E662', u'APPLE SSD SM128E'] True
[u'APPLE SSD SM128E'] False
[u'APPLE SSD SM128E', u'APPLE SSD SM128E'] False

可与列表理解一起使用,以生成符合条件的列表:

>>> [ex for ex in examples if all(any(r in s for s in ex) for r in must_have_list)]
[[u'APPLE SSD SM128E', u'APPLE HDD HTS541010A9E662'], [u'APPLE SSD SD0128F', u'APPLE HDD ST3000DM001'], [u'APPLE HDD HTS541010A9E662', u'APPLE HDD HTS541010A9E662', u'APPLE SSD SM128E']]

在这种情况下不需要regex,但是如果测试每个字符串都需要regex,则可以使用re.search而不是in。你知道吗

例如,假设您想知道被测试的子字符串是独立的,而不是另一个单词的一部分,比如SSDHYBRID

for ex in examples:
    print ex, all(any(re.search(r'\b{}\b'.format(r), s) for s in ex) for r in must_have_list)
# same output...

如您的示例所示,如果要测试的模式始终是字符串的初始部分,则比较简单:

for must_have in must_have_list:
    notInList = True
    for example in example_device_list:
        if example.startswith(must_have):
            notInList = False
            break
    if notInList: return False
return True

如果它可以是一个内部字符串,那么就必须使用must_have in example而不是startswith,这增加了算法的复杂性。你知道吗

额外的优化将是删除一个示例设备,发现它没有测试其他必备品。你知道吗

最后,您可以将整个过程翻过来,遍历每个示例设备上的示例列表,删除一个musthave作为本示例的前缀,直到没有musthave为止。根据必有列表和示例列表的大小,将必有列表复制到新的dict(或集合中的集合)以缩短搜索时间是有意义的。你知道吗

相关问题 更多 >

    热门问题