【问题标题】:How to handle lists as single values in csv with Python如何使用 Python 将列表作为 csv 中的单个值处理
【发布时间】:2015-09-26 01:46:24
【问题描述】:

我正在处理一个 csv 导入,但遇到了一个应该是列表形式但被读取为字符串的值的问题。

其中一个 csv 行如下所示:

    ['name1', "['name2', 'name3']"]

如您所见,第二列中的值是一个列表,但被读取为字符串。我的问题是我需要遍历该列表,并且该列表的长度可能因行而异。

我想知道问题出在哪里。 csv read 不能处理列表吗?有没有办法将第二列中的字符串转换为列表而不是使用正则表达式? 这是我正在运行的代码:

    import csv
    import os

    content = []
    file_path = os.path.abspath(file)
    if os.path.exists(file_path):
      with open(file_path, 'rb') as csvfile:
        csvreader = csv.reader(csvfile, delimiter = ',')
      for row in csvreader:
        content.append(row)
      for row in content[1:5]:
        print row
      print row[0], row[1]
      for name in row[1]:
        print name

输出行看起来如上,但是当遍历 row[1] 时,它不会遍历名称列表,而是遍历每个字符。有人有想法吗? 提前感谢您的帮助!

【问题讨论】:

  • 不,csv 模块无法将字符串转换为列表,您可以添加一个输入示例吗?您是如何最终将列表写入文件的?
  • 感谢@PadraicCunningham 的快速回答。在另一个应用程序中,将一个单元格中的多个字符串值保存到 csv 是有意义的。行看起来像第一个示例 ['name1', "['name2', 'name3']"]。可能有更好的方法来处理这个问题?
  • 为什么结构是['name1', "['name2', 'name3']"].?嵌套列表如何结束?
  • @PadraicCunningham 我将提供更多背景信息。 csv 显示不同用户之间的交互。所以整行如下所示:[date, text, id, 'name1', "['name2', 'name3']"] 表示 user1 提到了 user2 和 user3。在创建 csv 时,它似乎是最方便的解决方案
  • 我认为也许存储 dicts 或者使用 pandas 是个好主意,你在用这些数据做什么?

标签: python regex list csv


【解决方案1】:

将字符串转换为列表的简单方法是使用ast.literal_eval 函数。

例子-

>>> import ast
>>> s = "['name2', 'name3']"
>>> s
"['name2', 'name3']"
>>> l = ast.literal_eval(s)
>>> l
['name2', 'name3']
>>> type(l)
<class 'list'>

来自 ast documentation -

ast.literal_eval(node_or_string)

安全地评估包含 Python 文字或容器显示的表达式节点或 Unicode 或 Latin-1 编码字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、数字、元组、列表、字典、布尔值和无。

但如果您的完整 csv 看起来像这样,您应该考虑使用 json 来解析 csv,而不是 csv 模块。

【讨论】:

    【解决方案2】:
    x=['name1', "['name2', 'name3']"]
    import re
    print [ast.literal_eval(i) if re.match(r"\[.*?\]",i) else i for i in x ]
    

    输出:['name1', ['name2', 'name3']]

    您可以使用ast.literal_evalre 将列表中的字符串转换为列表,而让其他字符串保持原样。

    【讨论】:

      【解决方案3】:

      试试这个,使用literal_eval将字符串转换为对应的class

      from ast import literal_eval
      for name in literal_eval(row[1]):
         print name
      

      for name in eval(row[1]):
         print name
      

      【讨论】:

        【解决方案4】:

        考虑到你的第二个列表项是一个有效的python数据类型,你可以使用ast.literal_eval来解析字符串

        >>> import ast
        >>> ast.literal_eval("['name2', 'name3']")
        ['name2', 'name3']
        

        因此,在您的特定情况下,您可能需要执行以下操作

          .............
          row[1] = ast.literal_eval(row[1])
          print row[0], row[1]
          for name in row[1]:
            print name    
        

        【讨论】:

          猜你喜欢
          • 2018-02-25
          • 2015-05-17
          • 2020-01-13
          • 1970-01-01
          • 2016-07-04
          • 2016-10-02
          • 2014-05-24
          • 1970-01-01
          相关资源
          最近更新 更多