繁体   English   中英

过滤字符串列表,使其不包含来自另一个列表的任何字符串作为子字符串

[英]Filter list of strings to not contain any of the string from another list as a substring

我有以下代码来选择未包含在另一个列表中的值。

import re
isbn  = ["1111","2222","3333","4444","5555"]
sku = ["k1 1111", "k2 2222", "k3 3333", "k4 4444", "k5 5555", "k6 6666", "k7 7777", "k8 8888" ,"k9 1111"]

for x in isbn:
    for i in sku:
        if x not in i:
            print (i)

预期结果应如下:

k6 6666
k7 7777
k8 8888

但我得到了所有无与伦比的价值观。 如上所示,我怎样才能得到预期的结果。

你应该在你的循环中使用any 事实上,你可以使用下面的列表理解来实现它:

>>> list_1  = ["1111","2222","3333","4444","5555"]
>>> list_2 = ["k1 1111", "k2 2222", "k3 3333", "k4 4444", "k5 5555", "k6 6666", "k7 7777", "k8 8888" ,"k9 1111"]

>>> [x for x in list_2 if not any( y in x for y in list_1)]
['k6 6666', 'k7 7777', 'k8 8888']

如果list_1任何字符串作为list2子字符串存在,则any将返回True 一旦找到匹配,它将使迭代短路(不检查其他匹配)并将结果返回True

如果您对使用any不感兴趣,可以使用以下for循环获得相同的结果:

for x in list_2:
    for y in list_1:
        if y in x:
            break
    else:
        print(x)

这将打印您想要的输出:

k6 6666
k7 7777
k8 8888

您需要先测试isbn 所有值,然后才能得出这些值中的所有值。

而不是首先遍历isbn ,循环遍历sku并使用每个isbn值测试该值; any()函数使得更容易和更有效:

for value in sku:
    if not any(i in value for i in isbn):
        print(value)

更高效的仍然是拆分 ISBN部分,并测试一组:

isbn_set = set(isbn)
for value in sku:
    isbn_part = value.partition(' ')[-1]  # everything after the first space
    if isbn_part not in isbn_set:
        print(value)

这避免了在isbn altogther上的循环; 集合成员测试需要O(1)恒定时间; 对于N skus和M ISBN值,这使得O(N)循环(对O(NM)循环与any() )。

可以将任一版本转换为列表解析以生成匹配列表; 然后首选的设置版本变为:

isbn_set = set(isbn)
not_matched = [value for value in sku if value.partition(' ')[-1] not in isbn_set]

演示后者:

>>> isbn  = ["1111","2222","3333","4444","5555"]
>>> sku = ["k1 1111", "k2 2222", "k3 3333", "k4 4444", "k5 5555", "k6 6666", "k7 7777", "k8 8888" ,"k9 1111"]
>>> isbn_set = set(isbn)
>>> [value for value in sku if value.partition(' ')[-1] not in isbn_set]
['k6 6666', 'k7 7777', 'k8 8888']

如果你从一个集合中删除匹配,那么左边的集合就是你所追求的:

码:

skus = set(sku)
for x in isbn:
    skus -= {i for i in skus if x in i}

测试代码:

isbn = ["1111", "2222", "3333", "4444", "5555"]
sku = ["k1 1111", "k2 2222", "k3 3333", "k4 4444", "k5 5555", "k6 6666",
       "k7 7777", "k8 8888", "k9 1111"]

skus = set(sku)
for x in isbn:
    skus -= {i for i in skus if x in i}
print(skus)

结果:

{'k6 6666', 'k7 7777', 'k8 8888'}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM