我正在处理一个csv导入并遇到一个问题,其值应该是列表形式,但读作字符串。
其中一个csv行如下所示:
['name1', "['name2', 'name3']"]
正如您所看到的,第二列中的值是一个列表,但是作为字符串读取。我的问题是我需要遍历该列表,该列表的长度可能因行而异。
我想知道问题出在哪里。 csv可以读取不处理列表吗?有没有办法将第二列中的字符串转换为列表而不是使用正则表达式? 这是我正在运行的代码:
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]进行迭代时,它不会遍历名称列表而是遍历每个单个字符。有人有个主意吗? 在此先感谢您的帮助!
答案 0 :(得分:3)
将字符串转换为列表的简便方法是使用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文字结构:字符串,数字,元组,列表,dicts,布尔值和None。
但如果您的完整csv看起来像那样,您应该考虑使用json
来解析csv而不是csv
模块。
答案 1 :(得分:1)
考虑到您的第二个列表项是有效的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
答案 2 :(得分:1)
尝试使用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
答案 3 :(得分:0)
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_eval
和re
将列表中的字符串转换为列表,并保留其他字符串。