【问题标题】:Filter list based on another list in python根据python中的另一个列表过滤列表
【发布时间】:2022-02-16 06:11:24
【问题描述】:

我正在尝试使用以下代码根据另一个 list2 过滤 list1

import csv

with open('screen.csv') as f: #A file with a list of all the article titles
    reader = csv.reader(f)
    list1 = list(reader)

print(list1)

list2 = ["Knowledge Management", "modeling language"] #key words that article title should have (at least one of them)
list2 = [str(x) for x in list2]

occur = [i for i in list1  for j in list2 if str(j) in i]

print(occur)

但输出为空。

我的list1 看起来像这样:

【问题讨论】:

  • 也许那些确切的短语不存在?
  • 这里是我手动搜索的标题之一An Integrated Method for Knowledge Management in Product Configuration Projects,其中包含知识管理来测试它

标签: python filtering


【解决方案1】:

list_1 实际上是一个列表列表,而不是字符串列表,因此您需要在尝试比较元素之前将其展平(例如通过doing this):

list_1 = [['foo bar'], ['baz beep bop']]
list_2 = ['foo', 'bub']

flattened_list_1 = [
    element 
    for sublist in list_1 
    for element in sublist
]
occurrences = [
    phrase 
    for phrase in flattened_list_1 if any(
        word in phrase 
        for word in list_2
    )
]
print(occurrences)

# output:
# ['foo bar']

【讨论】:

  • 我尝试了第一个代码并完美运行,谢谢
  • 你没有从这里使用集合中受益,因为唯一使用的 in 运算符是进行子字符串匹配,而不是集合成员资格测试。不要被in 关键字也用于for x in y 循环所迷惑,这根本不是成员资格测试。
  • @Blckknght 是的,你是对的 - “成员资格检查”(子字符串匹配)实际上是在 word in phrase 中完成的......我将编辑第二部分以免混淆其他人。
【解决方案2】:
import pandas as pd 
import numpy as np
df = pd.DataFrame(data) 
print(df[df.column_of_list.map(lambda x: np.isin(x, another_list).all())])
#OR
print(df[df[0].map(lambda x: np.isin(x, another_list).all())])

尝试使用真实数据:

import numpy as np
import pandas as pd 
data = ["Knowledge Management", "modeling language"]
another_list=["modeling language","natural language"]
df = pd.DataFrame(data) 
a = df[df[0].map(lambda x: np.isin(x, another_list).all())]

print(a)

【讨论】:

  • import pandas as pd import numpy as np df = pd.read_csv('screen.csv') list2 = ["Knowledge Management", "modeling language"] print(df[df[0].map(lambda x: np.isin(x, list2).all())])
  • 但我收到错误raise KeyError(key) from err KeyError: 0
  • @Greencolor 我用真实数据编辑了答案,看看你的 csv 怎么样?
【解决方案3】:

您的list1 是一个列表列表,因为您用来创建它的csv.reader 总是返回每一行的列表,即使只有一个项目。 (如果您希望每一行都有一个名称,我不确定您为什么在这里使用 csv,这只会成为一个障碍。)

稍后,当您检查 if str(j) in i 作为过滤列表理解的一部分时,您正在测试字符串 j 是否存在于列表 i 中。由于list2 中的值不是完整的标题而是关键短语,因此您不会找到任何匹配项。如果你检查内部字符串,你会得到子字符串检查,但是当你测试列表成员时,它必须是完全匹配的。

可能解决此问题的最佳方法是取消 list1 中的嵌套列表。尝试使用以下方法创建它:

with open('screen.csv') as f:
    list1 = [line.strip() for line in f]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多