Python CSV строка в массив

187

Кто-нибудь знает простую библиотеку или функцию для анализа строки, закодированной в csv, и превращения ее в массив или словарь?

Я не думаю, что мне нужен встроенный модуль csv, потому что во всех примерах, которые я видел, используются пути к файлам, а не строки.

Дрю ЛеСюр
источник

Ответы:

259

Вы можете преобразовать строку в объект файла, используя, 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))

Или вы можете просто перевести split()эту строку в строки, используя в \nкачестве разделителя, а затем split()каждую строку в значения, но таким образом вы должны знать о кавычках, поэтому использование csvмодуля является предпочтительным.

На Python 2 вы должны импортировать StringIOкак

from StringIO import StringIO

вместо.

Михал Никлас
источник
6
метод split не сработал бы, если бы его CSV-файл содержал строки с запятыми
Карсон Майерс
3
или
заключенные в
28
Python 3 теперь использует io.StringIO. (Надеюсь, сэкономим немного времени пользователям Python 3). так что импортируйте io и io.StringIO.
JStrahl
3
Вместо .split('\n'), вы можете использовать .splitlines().
Денилсон Са Майя
1
Нет, очень хорошо работает с польскими буквами с огонками :-)
Михал Никлас
70

Все просто - модуль 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']]
adamk
источник
4
Полезно знать, но имейте в виду, что .split('\n')будут происходить странные вещи, если ваши поля содержат переводы строк.
Инамати
1
@Inaimathi, если это csv, переводы строк внутри должны быть экранированы.
Джон Ла Рой
Символы новой строки не нужно экранировать, если поле указано в кавычках.
Джонатан
1
Эта функциональность плохо документирована. Спасибо.
Cowlinator
13

Официальный документ для 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))
soulmachine
источник
11
>>> 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
ПНВ
источник
«Простое лучше, чем сложное!»
Абделуахаб
9
-1 Проблема с этим решением состоит в том, что оно не учитывает «экранирование строки», то есть 3, "4,5,6, 6должно рассматриваться как три поля вместо пяти.
Zz'Rot
Простой, но работает только в некоторых конкретных случаях, это не общий код синтаксического анализа CSV
Кристоф Русси,
8

Как уже отмечали другие, 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
roskakori
источник
Убедитесь, что в файле Unicode отсутствует спецификация (Marker Order Marker)
Pierre
1
Относительно спецификации: Python должен обнаруживать и пропускать официальные спецификации в UTF-32, UTF-16 и т. Д. Чтобы пропустить неофициальную спецификацию Microsoft для UTF-8, используйте 'utf-8-sig'вместо кодека 'utf-8'.
роскакори
7

Согласно документации:

И хотя модуль напрямую не поддерживает синтаксический анализ строк, это легко сделать:

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

Просто включите вашу строку в один список элементов.

Импорт StringIO кажется мне немного излишним, когда этот пример явно указан в документации.

roundar
источник
3

https://docs.python.org/2/library/csv.html?highlight=csv#csv.reader

csvfile может быть любым объектом, который поддерживает протокол итератора и возвращает строку каждый раз, когда вызывается его метод next ()

Таким образом, StringIO.StringIO(), str.splitlines()или даже генератор все хорошо.

ivan_pozdeev
источник
2

Вот альтернативное решение:

>>> 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']]

Вот документация

chfw
источник
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']]
JIMS
источник
0

Panda - довольно мощная и умная библиотека для чтения CSV на Python

Простой пример здесь, у меня есть файл example.zip с четырьмя файлами в нем.

EXAMPLE.zip
 -- example1.csv
 -- example1.txt
 -- example2.csv
 -- example2.txt

from zipfile import ZipFile
import pandas as pd


filepath = 'EXAMPLE.zip'
file_prefix = filepath[:-4].lower()

zipfile = ZipFile(filepath)
target_file = ''.join([file_prefix, '/', file_prefix, 1 , '.csv'])

df = pd.read_csv(zipfile.open(target_file))

print(df.head()) # print first five row of csv
print(df[COL_NAME]) # fetch the col_name data

Когда у вас есть данные, вы можете манипулировать ими со списком или другими форматами.

webbyfox
источник