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

194

У меня есть файл CSV с около 2000 записей.

Каждая запись имеет строку и категорию:

This is the first line,Line1
This is the second line,Line2
This is the third line,Line3

Мне нужно прочитать этот файл в список, который выглядит следующим образом:

data = [('This is the first line', 'Line1'),
        ('This is the second line', 'Line2'),
        ('This is the third line', 'Line3')]

Как можно импортировать этот CSV в список мне нужно с помощью Python?

MorganTN
источник
2
Затем используйте csvмодуль: docs.python.org/2/library/csv.html
furas
4
Если есть ответ, который подходит вашему вопросу, примите его.
Мацей Гол

Ответы:

308

Используя модуль CSV :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = list(reader)

print(data)

Вывод:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]

Если вам нужны кортежи:

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    data = [tuple(row) for row in reader]

print(data)

Вывод:

[('This is the first line', 'Line1'), ('This is the second line', 'Line2'), ('This is the third line', 'Line3')]

Старый ответ Python 2, также с использованием csvмодуля:

import csv
with open('file.csv', 'rb') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print your_list
# [['This is the first line', 'Line1'],
#  ['This is the second line', 'Line2'],
#  ['This is the third line', 'Line3']]
Мацей Гол
источник
4
Почему вы используете «rb» вместо «r»?
imrek
5
@DrunkenMaster, bфайл открывается в двоичном режиме, а не в текстовом режиме. В некоторых системах текстовый режим означает, что \nпри чтении или записи будет преобразовываться в новую строку для конкретной платформы. Смотрите документы .
Мачей Гол
7
Это не работает в Python 3.x: «csv.Error: итератор должен возвращать строки, а не байты (вы открывали файл в текстовом режиме?)» Смотрите ответ ниже, который работает в Python 3.x
Гилберт,
2
чтобы сэкономить несколько секунд времени на отладку, вам, вероятно, следует добавить примечание для первого решения, такого как «версия Python 2.x»
paradite
Как использовать ваше первое решение, но только с некоторыми столбцами из файла CSV?
Сигур
54

Обновлено для Python 3 :

import csv

with open('file.csv', newline='') as f:
    reader = csv.reader(f)
    your_list = list(reader)

print(your_list)

Вывод:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
seokhoonlee
источник
Указание 'r'является режимом по умолчанию, поэтому указывать его не нужно. В документах также упоминается, что если csvfile является файловым объектом, его следует открыть с помощью newline = ''.
AMC
44

Панды неплохо справляются с данными. Вот один пример, как его использовать:

import pandas as pd

# Read the CSV into a pandas data frame (df)
#   With a df you can do many things
#   most important: visualize data with Seaborn
df = pd.read_csv('filename.csv', delimiter=',')

# Or export it in many ways, e.g. a list of tuples
tuples = [tuple(x) for x in df.values]

# or export it as a list of dicts
dicts = df.to_dict().values()

Одним из больших преимуществ является то, что панды автоматически работают со строками заголовков.

Если вы не слышали о Seaborn , я рекомендую взглянуть на это.

Смотрите также: Как мне читать и записывать CSV-файлы с помощью Python?

Панды № 2

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
dicts = df.to_dict('records')

Содержание df:

     country   population population_time    EUR
0    Germany   82521653.0      2016-12-01   True
1     France   66991000.0      2017-01-01   True
2  Indonesia  255461700.0      2017-01-01  False
3    Ireland    4761865.0             NaT   True
4      Spain   46549045.0      2017-06-01   True
5    Vatican          NaN             NaT   True

Содержание диктов

[{'country': 'Germany', 'population': 82521653.0, 'population_time': Timestamp('2016-12-01 00:00:00'), 'EUR': True},
 {'country': 'France', 'population': 66991000.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': True},
 {'country': 'Indonesia', 'population': 255461700.0, 'population_time': Timestamp('2017-01-01 00:00:00'), 'EUR': False},
 {'country': 'Ireland', 'population': 4761865.0, 'population_time': NaT, 'EUR': True},
 {'country': 'Spain', 'population': 46549045.0, 'population_time': Timestamp('2017-06-01 00:00:00'), 'EUR': True},
 {'country': 'Vatican', 'population': nan, 'population_time': NaT, 'EUR': True}]

Панды № 3

import pandas as pd

# Get data - reading the CSV file
import mpu.pd
df = mpu.pd.example_df()

# Convert
lists = [[row[col] for col in df.columns] for row in df.to_dict('records')]

Содержание listsэто:

[['Germany', 82521653.0, Timestamp('2016-12-01 00:00:00'), True],
 ['France', 66991000.0, Timestamp('2017-01-01 00:00:00'), True],
 ['Indonesia', 255461700.0, Timestamp('2017-01-01 00:00:00'), False],
 ['Ireland', 4761865.0, NaT, True],
 ['Spain', 46549045.0, Timestamp('2017-06-01 00:00:00'), True],
 ['Vatican', nan, NaT, True]]
Мартин Тома
источник
tuples = [tuple(x) for x in df.values]может быть написано tuples = list(df.itertuples(index=False))вместо Обратите внимание, что документы Pandas препятствуют использованию .valuesв пользу .to_numpy(). Третий пример меня смущает. Во-первых, потому что переменная названа tuples, что подразумевает, что это список кортежей, тогда как на самом деле это список списков. Во-вторых, потому что, насколько я могу судить, все выражение можно заменить на df.to_list(). Я также не знаю, действительно ли второй пример здесь уместен.
AMC
9

Обновление для Python3:

import csv
from pprint import pprint

with open('text.csv', newline='') as file:
    reader = csv.reader(file)
    res = list(map(tuple, reader))

pprint(res)

Вывод:

[('This is the first line', ' Line1'),
 ('This is the second line', ' Line2'),
 ('This is the third line', ' Line3')]

Если csvfile является файловым объектом, его следует открыть с помощью newline=''.
модуль CSV

Исчисление
источник
Зачем использовать list(map())над списком понимания? Также обратите внимание на пробелы в начале каждого элемента второго столбца.
AMC
5

Если вы уверены, что в вводе нет запятых, кроме разделения категории, вы можете прочитать файл построчно и разделить на части ,, а затем отправить результат вList

Тем не менее, похоже, что вы смотрите на файл CSV, поэтому вы можете рассмотреть возможность использования модулей для него

Микель
источник
4
result = []
for line in text.splitlines():
    result.append(tuple(line.split(",")))
Acid_Snake
источник
1
Можете ли вы добавить немного объяснений к этому сообщению? Код только (иногда) хорош, но код и объяснение (в большинстве случаев) лучше
Барранка
3
Я знаю, что комментарию Барранки больше года, но для любого, кто наткнулся на это и не может понять это: для строки в text.splitlines (): помещает каждую отдельную строку во временную переменную "line". line.split (",") создает список строк, разделенных запятой. tuple (~) помещает этот список в кортеж, а append (~) добавляет его к результату. После цикла результат представляет собой список кортежей, каждый кортеж которого содержит строку, а каждый элемент кортежа - элемент в файле CSV.
Луи
В дополнение к тому, что сказал @Louis, нет необходимости использовать .read().splitlines(), вы можете выполнять итерацию по каждой строке файла напрямую: for line in in_file: res.append(tuple(line.rstrip().split(",")))Также обратите внимание, что использование .split(',')означает, что каждый элемент второго столбца будет начинаться с дополнительного пробела.
AMC
Приложение к коду, которым я только что поделился: line.rstrip()-> line.rstrip('\n').
AMC
3

Как уже говорилось в комментариях, вы можете использовать csvбиблиотеку в Python. csv означает значения, разделенные запятыми, что кажется именно вашим случаем: метка и значение, разделенные запятой.

Будучи категорией и типом значения, я бы предпочел использовать тип словаря вместо списка кортежей.

В любом случае в приведенном ниже коде я показываю оба способа: dэто словарь и lсписок кортежей.

import csv

file_name = "test.txt"
try:
    csvfile = open(file_name, 'rt')
except:
    print("File not found")
csvReader = csv.reader(csvfile, delimiter=",")
d = dict()
l =  list()
for row in csvReader:
    d[row[1]] = row[0]
    l.append((row[0], row[1]))
print(d)
print(l)
Франческо Бой
источник
Почему бы не использовать менеджер контекста для обработки файла? Почему вы смешиваете два разных соглашения об именах переменных? Разве не (row[0], row[1])слабее / более подвержен ошибкам, чем просто использование tuple(row)?
AMC
Почему вы думаете, что выполнение кортежа (строки) менее подвержено ошибкам? На какое соглашение об именах переменных вы ссылаетесь? Пожалуйста, свяжите официальное соглашение об именах Python. Насколько я знаю, try -except - это хороший способ обработки файлов: что вы подразумеваете под обработчиком контекста?
Франческо Бой
Почему вы думаете, что кортеж (строка) менее подвержен ошибкам? Потому что это не требует, чтобы вы записывали каждый индекс вручную. Если вы допустили ошибку или количество элементов изменилось, вы должны вернуться и изменить свой код. Попытка-исключение хороша, контекстные менеджеры являются оператором with. Вы можете найти множество ресурсов по этому вопросу, например, этот .
AMC
Я не вижу, как менеджер контекста был бы лучше, чем старый хороший блок try-кроме. С другой стороны, положительным моментом является то, что вы печатаете меньше кода; в остальном, если количество элементов (я думаю, вы имеете в виду количество столбцов) меняет мое, то лучше, потому что он извлекает только нужные значения, а другой - все Excel. Без каких-либо конкретных требований вы не можете сказать, что лучше, поэтому спорить о том, что лучше, - пустая трата времени: в этом случае оба действительны
Франческо Бой
Я не вижу, как менеджер контекста был бы лучше, чем старый хороший блок try-кроме. Пожалуйста, смотрите мой предыдущий комментарий, менеджер контекста не заменит попробуйте.
AMC
2

Достаточно простого цикла:

lines = []
with open('test.txt', 'r') as f:
    for line in f.readlines():
        l,name = line.strip().split(',')
        lines.append((l,name))

print lines
Хантер МакМиллен
источник
1
Что если в некоторых записях есть запятые?
Тони Эннис
@TonyEnnis Тогда вам нужно будет использовать более продвинутый цикл обработки. Ответ Maciej выше показывает, как использовать синтаксический анализатор csv, который поставляется с Python, для выполнения этой операции. Этот парсер, скорее всего, имеет всю необходимую логику.
Хантер МакМиллен
1

К сожалению, я не считаю ни один из существующих ответов особенно удовлетворительным.

Вот простое и полное решение Python 3 с использованием модуля csv .

import csv

with open('../resources/temp_in.csv', newline='') as f:
    reader = csv.reader(f, skipinitialspace=True)
    rows = list(reader)

print(rows)

Обратите внимание на skipinitialspace=Trueаргумент. Это необходимо, поскольку, к сожалению, CSV OP содержит пробелы после каждой запятой.

Вывод:

[['This is the first line', 'Line1'], ['This is the second line', 'Line2'], ['This is the third line', 'Line3']]
AMC
источник
0

Немного расширив свои требования и предположив, что вы не заботитесь о порядке строк и хотите, чтобы они были сгруппированы по категориям, вам может помочь следующее решение:

>>> fname = "lines.txt"
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> with open(fname) as f:
...     for line in f:
...         text, cat = line.rstrip("\n").split(",", 1)
...         dct[cat].append(text)
...
>>> dct
defaultdict(<type 'list'>, {' CatA': ['This is the first line', 'This is the another line'], ' CatC': ['This is the third line'], ' CatB': ['This is the second line', 'This is the last line']})

Таким образом, вы получаете все соответствующие строки в словаре под ключом, являющимся категорией.

Ян Влчинский
источник
0

Вот самый простой способ в Python 3.x импортировать CSV в многомерный массив, и он содержит всего 4 строки кода, ничего не импортируя!

#pull a CSV into a multidimensional array in 4 lines!

L=[]                            #Create an empty list for the main array
for line in open('log.txt'):    #Open the file and read all the lines
    x=line.rstrip()             #Strip the \n from each line
    L.append(x.split(','))      #Split each line into a list and add it to the
                                #Multidimensional array
print(L)
Джейсон Баучер
источник
Будьте осторожны, это список, а не массив! Почему бы не использовать менеджер контекста для правильной обработки файлового объекта? Обратите внимание, что это решение оставляет дополнительные пробелы во втором элементе в каждой строке, и что оно потерпит неудачу, если какие-либо данные содержат запятую.
AMC
-1

Далее следует фрагмент кода, который использует модуль csv, но извлекает содержимое файла file.csv в список dicts, используя первую строку, которая является заголовком таблицы csv

import csv
def csv2dicts(filename):
  with open(filename, 'rb') as f:
    reader = csv.reader(f)
    lines = list(reader)
    if len(lines) < 2: return None
    names = lines[0]
    if len(names) < 1: return None
    dicts = []
    for values in lines[1:]:
      if len(values) != len(names): return None
      d = {}
      for i,_ in enumerate(names):
        d[names[i]] = values[i]
      dicts.append(d)
    return dicts
  return None

if __name__ == '__main__':
  your_list = csv2dicts('file.csv')
  print your_list
Алексей Антоненко
источник
1
Почему бы просто не использовать csv.DictReader?
AMC