有没有办法验证一个列表中的每个项目至少存在一次来自另一个列表?

时间:2017-05-06 01:02:58

标签: python

我正在尝试验证列表中的每个字符串是否在另一个列表中至少存在一次。我一直坚持的问题是字符串永远不会完全匹配,所以我需要某种形式的正则表达式/通配符。

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

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

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

True其中一个发现

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

False仅找到2x APPLE 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

如何使用正则表达式验证一个列表中的每个项目是否存在于另一个列表中?

3 个答案:

答案 0 :(得分:1)

如果在您的示例中,要测试的模式始终是字符串的 initial 部分,则稍微简单一些:

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而不是startwith,这会提高算法的复杂性。

其他优化措施是删除一个未对其他必须进行测试的示例设备。

最后,您可以将整个过程内部翻转出来,并遍历每个示例设备上的示例列表,删除已发现为此示例前缀的musthave,直到没有剩下必须的为止。根据必须具有列表和示例列表的大小,将musthaves复制到新的dict(或从集合中设置)以改善搜索时间是有意义的。

答案 1 :(得分:1)

不使用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

答案 2 :(得分:0)

您可以使用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']]

在这种情况下不需要正则表达式,但如果测试每个字符串需要它,则可以使用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...