Python中通过另一个列表对子字符串过滤列表元素

4

我有两个列表,看起来像:

list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
list2 = [100, 200]

我希望用list2中的元素过滤list1的子串,并获得以下期望输出:

outcome = ['bj-100-cy', 'sh-200-pd']

当你执行以下操作时:

list1 = str(list1)
list2 = str(list2)
outcome = [x for x in list2 if [y for y in list1 if x in y]]

我得到了这样的结果:['[', '1', '0', '0', ',', ' ', '2', '0', '0', ']']。我应该如何正确过滤它?谢谢。
相关参考资料: 在Python中,是否可以通过另一个字符串列表来过滤子字符串列表?
7个回答

7
列表推导式和any:
[i for i in list1 if any(i for j in list2 if str(j) in i)]

any用于检查list2中的任何一个元素是否是正在迭代的list1项(使用__contains__)的子字符串。

示例:

In [92]: list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
    ...: list2 = [100, 200]
    ...: 

In [93]: [i for i in list1 if any(i for j in list2 if str(j) in i)]
Out[93]: ['bj-100-cy', 'sh-200-pd']

谢谢,我会用你的脚本来处理我的真实数据(几乎与这里的示例数据相同),我需要添加 list2 = [str(x) for x in list2],否则我会得到 TypeError: 'in <string>' requires string as left operand, not int - ah bon
@ahbon 这很奇怪,因为我在 str(j) 中进行了类型转换:any(i for j in list2 if str(j) in i) - heemayl
是的,我重新阅读了数据并再次尝试,现在没问题了,感谢这位发帖人提供的所有帮助。 - ah bon

3

您可以使用任何:

list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
list2 = [100, 200]
list2 = [str(x) for x in list2]

outcome = [s for s in list1 if any(x in s for x in list2)]

any函数在你给它的条件中只要有一个为True,它就会返回True


2
list1 = str(list1)
list2 = str(list2)

你正在使用上述语句将列表转换为字符串。因此,当你在for循环中迭代时,你是在迭代每个字符,而不是每个单词。
所以你应该删除字符串转换,改用以下的列表推导式。 另外,在你的输出文件中,你检查的不是list2中的单词是否在list1中,而是相反的。所以你得到了像100和200这样在list2中的字符。
修改后代码如下: ```python words = [word for word in list1 if word not in list2] ``` ```python with open(outcome_file, 'w') as f: f.write(' '.join(words)) ```
list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
list2 = [100, 200]
outcome = [x for x in list1 for y in list2 if str(y) in x]

1
你可以尝试这个:

list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
list2 = [100, 200]

outcome = []
for item in list1:
    if any(str(i) in item for i in list2):
        outcome.append(item)

输出:

['bj-100-cy', 'sh-200-pd']

1
另一种可选的列表推导式:

>>> list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
>>> list2 = [100, 200]
>>> occur = [i for i in list1  for j in list2 if str(j) in i]
>>> occur
['bj-100-cy', 'sh-200-pd']

1
你可以使用内置的 filter 方法按照条件筛选列表。你的条件需要使用 Python 的 in 操作符在 haystack ([['bj-100-cy','bj-101-hd',...]]) 中搜索 needle ([100, 200])。 我们可以使用 contains 方法来简化搜索语法。 代码
from operator import contains
filter(lambda x: any(contains(x,str(y)) for y in list2), list1)

例子

>>> list1 = ['bj-100-cy','bj-101-hd','sh-200-pd','sh-201-hp']
>>> list2 = [100, 200]
>>> for item in filter(lambda x: any(contains(x,str(y)) for y in list2), list1):
...     print(item)
...
bj-100-cy
sh-200-pd

1
你可以使用正则表达式:
import re

list1 = ['bj-100-cy', 'bj-101-hd', 'sh-200-pd', 'sh-201-hp']
list2 = [100, 200]

pattern = re.compile('|'.join(map(str, list2)))
list(filter(pattern.search, list1))
# ['bj-100-cy', 'sh-200-pd']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接