Как прочитать текстовый файл в список или массив с помощью Python


176

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

Текстовый файл отформатирован следующим образом:

0,0,200,0,53,1,0,255,...,0.

Где ...выше, там фактический текстовый файл имеет сотни или тысячи элементов.

Я использую следующий код, чтобы попытаться прочитать файл в список:

text_file = open("filename.dat", "r")
lines = text_file.readlines()
print lines
print len(lines)
text_file.close()

Вывод, который я получаю:

['0,0,200,0,53,1,0,255,...,0.']
1

По-видимому, это чтение всего файла в список только из одного элемента, а не из списка отдельных элементов. Что я делаю не так?


1
Просто как примечание. Похоже, этот вопрос следует перефразировать так: как прочитать файл csv в список на Python. Но я полагаюсь на первоначальные намерения ОП более 4 лет назад, которых я не знаю.
— демонголем



1
На самом деле, глядя на верхний ответ, это дубликат stackoverflow.com/questions/3277503/… .
— AMC

Ответы:


135

Вам придется разделить вашу строку на список значений, используя split()

Так,

lines = text_file.read().split(',')

1
Я думаю, что этот ответ может быть лучше ... Если вы рассматриваете многострочный .csvфайл (как упомянуто в OP), например, файл, содержащий буквенные символы 3 по строке ( a,b,c, d,e,fи т. Д.) И применяете процедуру, описанную выше, что вы получаете такой список: ['a', 'b', 'c\nd', 'e', ... ](обратите внимание на элемент 'c\nd'). Я хотел бы добавить, что, несмотря на описанную выше проблему, эта процедура объединяет данные из отдельных строк в одном мегаполисе, обычно не то, что мне нужно при обработке файла данных, ориентированного на записи.
— gboffi

раскол собирается покинуть новые строки. Не делайте этого, используйте csvмодуль или другой существующий парсер
— Жан-Франсуа Фабр

43

Вы также можете использовать numpy loadtxt как

from numpy import loadtxt
lines = loadtxt("filename.dat", comments="#", delimiter=",", unpack=False)

1
Мне это тоже нужно. Я заметил на Raspberry Pi, что NumPy работает очень медленно. Для этого приложения я вернулся, чтобы открыть файл и читать его построчно.
— Гус

2
Это также полезно для указания формата через dtype : data-typeпараметр. docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html Панды read_csv очень просты в использовании. Но я не видел способа указать формат для него. Он считывал числа из моего файла, а мне нужна была строка. Спасибо @Thiru за показ loadtxt.
— Озгур

1
если в txt-файлах содержатся строки, то должен быть указан dtype, поэтому он должен выглядеть следующим образом: lines = loadtxt ("filename.dat", dtype = str, comments = "#", delimiter = ",", unpack = False)
— Alex M981

19

Итак, вы хотите создать список списков ... Нам нужно начать с пустого списка

list_of_lists = []

Далее читаем содержимое файла построчно

with open('data') as f:
    for line in f:
        inner_list = [elt.strip() for elt in line.split(',')]
        # in alternative, if you need to use the file content as numbers
        # inner_list = [int(elt.strip()) for elt in line.split(',')]
        list_of_lists.append(inner_list)

Распространенным случаем является использование столбчатых данных, но наши единицы хранения - это строки файла, которые мы прочитали одна за другой, поэтому вы можете захотеть перенести свой список списков. Это можно сделать с помощью следующей идиомы

by_cols = zip(*list_of_lists)

Другое распространенное использование - дать имя каждому столбцу.

col_names = ('apples sold', 'pears sold', 'apples revenue', 'pears revenue')
by_names = {}
for i, col_name in enumerate(col_names):
    by_names[col_name] = by_cols[i]

так что вы можете работать с однородными элементами данных

 mean_apple_prices = [money/fruits for money, fruits in
                     zip(by_names['apples revenue'], by_names['apples_sold'])]

Большая часть того, что я написал, может быть ускорена с помощью csvмодуля из стандартной библиотеки. Другой сторонний модуль pandasпозволяет автоматизировать большинство аспектов типичного анализа данных (но имеет ряд зависимостей).


Обновление Хотя в Python 2 zip(*list_of_lists)возвращается другой (транспонированный) список списков, в Python 3 ситуация изменилась и zip(*list_of_lists)возвращает объект zip, который не является подписным.

Если вам нужен индексированный доступ, вы можете использовать

by_cols = list(zip(*list_of_lists))

это дает вам список списков в обеих версиях Python.

С другой стороны, если вам не нужен индексированный доступ и вам нужно просто создать словарь, индексированный по именам столбцов, zip-объект - это нормально ...

file = open('some_data.csv')
names = get_names(next(file))
columns = zip(*((x.strip() for x in line.split(',')) for line in file)))
d = {}
for name, column in zip(names, columns): d[name] = column

ОП сказал, что хочет получить список данных из CSV, а не «список списков». Просто используйте csvмодуль ...
— Blairg23

4

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

0,0,200,0,53,1,0,255,...,0.

Самый простой способ сделать это с помощью csvмодуля следующим образом:

import csv
with open('filename.dat', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')

Теперь вы можете легко выполнить итерацию spamreaderследующим образом:

for row in spamreader:
    print(', '.join(row))

Смотрите документацию для большего количества примеров.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.