Python CSV字符串转换为数组

247

有没有一个简单的库或函数可以解析csv编码的字符串,并将其转换为数组或字典?

我不认为我想要内置的csv模块,因为在我看到的所有示例中都使用文件路径,而不是字符串。

11个回答

357
您可以使用io.StringIO将字符串转换为文件对象,然后将其传递给csv模块:
from io import StringIO
import csv

scsv = """text,with,Polish,non-Latin,letters
1,2,3,4,5,6
a,b,c,d,e,f
gęś,zółty,wąż,idzie,wąską,dróżką,
"""

f = StringIO(scsv)
reader = csv.reader(f, delimiter=',')
for row in reader:
    print('\t'.join(row))

使用split()函数将其简化为按换行符分割的版本:

reader = csv.reader(scsv.split('\n'), delimiter=',')
for row in reader:
    print('\t'.join(row))

或者您可以直接使用\n作为分隔符将此字符串拆分成行,然后将每行拆分为值,但这种方式必须注意引用,因此最好使用csv模块。

Python 2中,您需要导入StringIO

from StringIO import StringIO

代替之。

8
如果他的CSV文件包含包含逗号的字符串,则split方法将无法正常工作。 - Carson Myers
3
将引号括起来的字符串作为值(带或不带逗号)。 - adamk
31
Python 3现在使用io.StringIO。(希望能为Python 3用户节省一些时间)。因此,需要导入io和io.StringIO。 - JStrahl
4
你可以使用 .splitlines() 替代 .split('\n') - Denilson Sá Maia
1
不,它与带有ogonki的波兰字母非常好地配合使用 :-) - Michał Niklas
显示剩余2条评论

85

简单 - csv模块也可以使用列表:

>>> a=["1,2,3","4,5,6"]  # or a = "1,2,3\n4,5,6".split('\n')
>>> import csv
>>> x = csv.reader(a)
>>> list(x)
[['1', '2', '3'], ['4', '5', '6']]

5
知道就好,但要记住,如果您的字段包含换行符,使用.split('\n')会产生奇怪的结果。 - Inaimathi
1
@Inaimathi,如果是CSV格式,则应该转义内部的换行符。 - John La Rooy
2
如果字段被引用,换行符就不需要转义。 - Jonathan Stray
1
此功能文档不完善。谢谢。 - cowlinator

28
官方文档中的csv.reader() https://docs.python.org/2/library/csv.html非常有帮助,其中写道:

文件对象和列表对象都适用。

import csv

text = """1,2,3
a,b,c
d,e,f"""

lines = text.splitlines()
reader = csv.reader(lines, delimiter=',')
for row in reader:
    print('\t'.join(row))

16

根据文档:

虽然该模块不直接支持解析字符串,但可以轻松地完成:

import csv
for row in csv.reader(['one,two,three']):
    print row

将您的字符串转换为单个元素列表即可。

对于这个例子来说,我认为导入StringIO有点过度了,因为它已经在文档中明确提到了。


9

正如其他人已经指出的那样,Python包含一个用于读写CSV文件的模块。只要输入字符保持在ASCII限制范围内,它就可以很好地工作。如果您想处理其他编码,则需要更多的工作。

Python文档中的csv模块实现了csv.reader的扩展,它使用相同的接口,但可以处理其他编码并返回Unicode字符串。只需从文档中复制并粘贴代码即可。之后,您可以像这样处理CSV文件:

with open("some.csv", "rb") as csvFile: 
    for row in UnicodeReader(csvFile, encoding="iso-8859-15"):
        print row

确保Unicode文件没有BOM(字节顺序标记)。 - Pierre
1
关于BOM:Python应该检测并跳过UTF-32、UTF-16等官方BOM。为了跳过UTF-8的非官方Microsoft BOM,请使用'utf-8-sig'作为编解码器,而不是'utf-8'。 - roskakori

7
不是通用的CSV解析器,但可用于带有逗号的简单字符串。
>>> a = "1,2"
>>> a
'1,2'
>>> b = a.split(",")
>>> b
['1', '2']

解析CSV文件的方法:

f = open(file.csv, "r")
lines = f.read().split("\n") # "\r\n" if needed

for line in lines:
    if line != "": # add other needed checks to skip titles
        cols = line.split(",")
        print cols

简单胜于复杂! - Abdelouahab
13
这种解决方案的问题在于它没有考虑到“字符串转义”,即3,"4,5,6, 6"应被视为三个字段而不是五个。 - Zz'Rot
简单但只适用于某些特定情况,这不是通用的CSV解析代码。 - Christophe Roussy

3

2
使用以下代码将csv加载到列表中:
import csv

csvfile = open(myfile, 'r')
reader = csv.reader(csvfile, delimiter='\t')
my_list = list(reader)
print my_list
>>>[['1st_line', '0'],
    ['2nd_line', '0']]

1
这是一个替代方案:

>>> import pyexcel as pe
>>> text="""1,2,3
... a,b,c
... d,e,f"""
>>> s = pe.load_from_memory('csv', text)
>>> s
Sheet Name: csv
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
| a | b | c |
+---+---+---+
| d | e | f |
+---+---+---+
>>> s.to_array()
[[u'1', u'2', u'3'], [u'a', u'b', u'c'], [u'd', u'e', u'f']]

这里是文档

0

对于仍在寻找可靠的方法将标准CSV str转换为list[str],以及反向转换的人,这里有两个函数,我从本网站和其他SO线程的一些答案中整理出来:

def to_line(row: list[str]) -> str:
    with StringIO() as line:
        csv.writer(line).writerow(row)
        return line.getvalue().strip()


def from_line(line: str) -> list[str]:
    return next(csv.reader([line]))

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