Как прочитать текстовый файл в список или массив с помощью 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.