如何从包含 nan 的类列表字符串中获取字符串列表?

How to get list of strings from list-like string that includes nan?

这是玩具示例,我有这样的字符串:

import numpy as np
z = str([np.nan, "ab", "abc"])

印刷 看起来像 "[nan, 'ab', 'abc']" 但我必须处理 z = str([np.nan, "ab", "abc"])

我想从 z 字符串列表中获取不包括 nan:

zz = ["ab", "abc"]

要清楚z是输入(字符串,看起来像列表),zz是想要的输出(列表)

如果 z 不包含 nan 就没有问题,这样 ast.literal_eval(z) 就可以完成工作,但是对于 nan 我会收到有关格式错误的节点或字符串的错误。

注意: np.nan 不必是第一个。

许多解决方案其中之一是

z = [nan, 'string', 'another_one']
string_list = []

for item in z :
    # find the object come from str Class and Append it to the list
    if item.__class__ == str:
            string_list.append(item)

使用 filter() 函数:

list(filter(lambda f: type(f)==str, z))

怎么样:

eval(z,{'nan':'nan'}) # if you can tolerate then: 
[i for i in eval(z,{'nan':'nan'}) if i != 'nan']

可能有安全方面的考虑。

ast.literal_eval 优于 eval 正是因为它允许的语句集非常有限。如文档中所述:“安全地评估表达式节点或包含 Python 文字或容器显示的字符串。提供的 字符串或节点可能仅包含以下 Python 文字结构:字符串、字节、数字、元组、列表、字典、集合、布尔值、None 和省略号。” np.nan 是其中的 none,因此无法对其进行评估。 处理这个问题的选择很少。

  • 通过在对字符串进行评估之前对其进行操作来删除 nan。如果您还想避免从实际字符串中删除 nan,则可能会出现问题。
  • 不建议 - 安全风险 - 如果你在命名空间
  • 中定义 nan 变量,标准 eval 可以解决这个问题
  • 最后,我认为最好的选择也是最难实现的:就像 here 解释的那样,你获取 ast 的源代码,将其子类化并重新实现 literal_eval它知道如何自己处理 nan 字符串的一种方式。

据我了解,您的目标是解析 csv 或类似文件。

如果您希望 trade-off 解决方案在大多数情况下都能正常工作,您可以使用正则表达式去掉“nan”。它会在包含子字符串 nan,(带逗号)的字符串上失败,但这似乎是一种不太可能的边缘情况。值得和你爆料的真实数据。

z = str([np.nan, "ab", np.nan, "nan,", "abc", "x nan , y", "x nan y"])

import re
literal_eval(re.sub(r'\bnan\s*,\s*', '', z))

输出:['ab', '', 'abc', 'x y', 'x nan y']