Cách đọc tệp văn bản vào danh sách hoặc mảng bằng Python


175

Tôi đang cố gắng đọc các dòng của một tệp văn bản vào một danh sách hoặc mảng trong python. Tôi chỉ cần có thể truy cập riêng lẻ bất kỳ mục nào trong danh sách hoặc mảng sau khi nó được tạo.

Tệp văn bản được định dạng như sau:

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

Trường hợp ...ở trên, có tập tin văn bản thực tế có hàng trăm hoặc hàng ngàn mục.

Tôi đang sử dụng đoạn mã sau để cố đọc tệp vào danh sách:

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

Đầu ra tôi nhận được là:

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

Rõ ràng nó đang đọc toàn bộ tập tin vào một danh sách chỉ một mục, thay vì danh sách các mục riêng lẻ. Tôi đang làm gì sai?


1
Chỉ là một ghi chú. Có vẻ như câu hỏi này nên được đọc lại như cách đọc tệp csv vào danh sách trong Python. Nhưng tôi đã trì hoãn ý định ban đầu của OP hơn 4 năm trước mà tôi không biết.
demongolem



1
Trong thực tế, nhìn vào câu trả lời hàng đầu, đây là một bản sao của stackoverflow.com/questions/3277503/iêu .
AMC

Câu trả lời:


135

Bạn sẽ phải chia chuỗi của mình thành một danh sách các giá trị bằng cách sử dụng split()

Vì thế,

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

1
Tôi nghĩ rằng câu trả lời này có thể làm tốt hơn cả ... Nếu bạn xem xét một multiline .csvtập tin (như đã đề cập bởi OP), ví dụ, một file chứa các ký tự chữ 3 bởi hàng ( a,b,c, d,e,f, vv) và áp dụng các thủ tục mô tả ở trên những gì bạn nhận được là một danh sách như thế này: ['a', 'b', 'c\nd', 'e', ... ](lưu ý mục này 'c\nd'). Tôi muốn nói thêm rằng, vấn đề nêu trên chưa được giải quyết, quy trình này thu gọn dữ liệu từ các hàng riêng lẻ trong một danh sách lớn, thường không phải là điều tôi muốn khi xử lý tệp dữ liệu hướng bản ghi.
gboffi

chia sẽ rời khỏi dòng mới. Đừng làm điều này, sử dụng csvmô-đun hoặc một số trình phân tích cú pháp hiện có khác
Jean-François Fabre

42

Bạn cũng có thể sử dụng loadtxt numpy như

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

1
Tôi cũng cần cái này Tôi nhận thấy trên một Raspberry Pi rằng numpy hoạt động rất chậm. Đối với ứng dụng này, tôi hoàn nguyên để mở một tập tin và đọc từng dòng một.
Guus

2
Điều này cũng hữu ích cho việc chỉ định định dạng quá, thông qua dtype : data-typetham số. docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html Pandas read_csv rất dễ sử dụng. Nhưng tôi đã không thấy một cách để xác định định dạng cho nó. Nó đang đọc float từ tập tin của tôi, trong khi tôi cần chuỗi. Cảm ơn @Thiru đã hiển thị loadtxt.
Ozgur Ozturk

1
nếu các tệp txt chứa các chuỗi, thì nên chỉ định dtype, vì vậy nó phải giống như lines = loadtxt ("filename.dat", dtype = str, bình luận = "#", delimiter = ",", unpack = Sai)
Alex M981

19

Vì vậy, bạn muốn tạo một danh sách các danh sách ... Chúng ta cần bắt đầu với một danh sách trống

list_of_lists = []

tiếp theo, chúng tôi đọc nội dung tập tin, từng dòng

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)

Một trường hợp sử dụng phổ biến là dữ liệu cột, nhưng các đơn vị lưu trữ của chúng tôi là các hàng của tệp, chúng tôi đã đọc từng cái một, vì vậy bạn có thể muốn hoán chuyển danh sách danh sách của mình. Điều này có thể được thực hiện với thành ngữ sau đây

by_cols = zip(*list_of_lists)

Một cách sử dụng phổ biến khác là đặt tên cho mỗi cột

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]

để bạn có thể hoạt động trên các mục dữ liệu đồng nhất

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

Hầu hết những gì tôi đã viết có thể được tăng tốc bằng cách sử dụng csvmô-đun, từ thư viện chuẩn. Một mô-đun bên thứ ba khác là pandas, cho phép bạn tự động hóa hầu hết các khía cạnh của phân tích dữ liệu điển hình (nhưng có một số phụ thuộc).


Cập nhật Trong khi trong Python 2 zip(*list_of_lists)trả về một danh sách danh sách (đã chuyển) khác, trong Python 3, tình huống đã thay đổi và zip(*list_of_lists)trả về một đối tượng zip không thể đăng ký được.

Nếu bạn cần truy cập được lập chỉ mục, bạn có thể sử dụng

by_cols = list(zip(*list_of_lists))

cung cấp cho bạn một danh sách các danh sách trong cả hai phiên bản Python.

Mặt khác, nếu bạn không cần truy cập được lập chỉ mục và điều bạn muốn chỉ là xây dựng một từ điển được lập chỉ mục theo tên cột, một đối tượng zip sẽ ổn ...

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

OP cho biết họ muốn có một danh sách dữ liệu từ CSV chứ không phải là "danh sách danh sách". Chỉ cần sử dụng csvmô-đun ...
Blairg23

4

Câu hỏi này là hỏi làm thế nào để đọc nội dung giá trị được phân tách bằng dấu phẩy từ tệp vào danh sách lặp lại:

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

Cách dễ nhất để làm điều này là với csvmô-đun như sau:

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

Bây giờ, bạn có thể dễ dàng lặp đi lặp lại spamreadernhư thế này:

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

Xem tài liệu để biết thêm ví dụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.