Python 筛选字符串列表,使其不包含其他列表中的任何字符串作为子字符串
我有以下代码来选择其他列表中不包含的值Python 筛选字符串列表,使其不包含其他列表中的任何字符串作为子字符串,python,string,python-3.x,list,Python,String,Python 3.x,List,我有以下代码来选择其他列表中不包含的值 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:
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
但我得到了所有不匹配的值。我如何才能获得上面所示的预期结果。您应该在循环中使用。事实上,您可以通过以下方式实现:
如果列表1
中的任何字符串作为子字符串出现在列表2中,则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
值测试该值;这样做更简单、更高效:
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个SKU和M个ISBN值,这将形成一个O(N)循环(与带有any()
的O(NM)循环)
任何一个版本都可以转换为a以生成匹配列表;然后,首选集合版本变为:
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']
如果从集合中删除匹配项,则剩余的集合就是您要查找的:
代码:
测试代码:
结果:
这不是最直观的路径,仍然是一个O(NM)解决方案。实际上,这比O(NM)更糟糕,因为您循环N个SKU以获得M个isbn值,而减法是另一个循环,最多可循环N个值,所以O(N**2M),比OP更糟糕。在底部代码中没有任何()。为什么else与for对齐而不是与if对齐。@如果您的for
循环在没有执行break
的情况下完成迭代,则将执行else
。如果您的if
条件返回True
,break
将停止内部循环,在这种情况下,否则
将不会执行。
>>> 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'}