2011-07-05 23 views
38

Tôi muốn đọc các số từ tệp thành mảng hai chiều.Làm thế nào để đọc các số từ tệp trong Python?

nội dung tập tin:

  • dòng chứa w, h
  • dòng h chứa w số nguyên cách nhau với không gian

Ví dụ:

4 3 
1 2 3 4 
2 3 4 5 
6 7 8 9 
+0

được bạn bị mắc kẹt ở đâu đó cụ thể? có một cái nhìn tại http://docs.python.org/tutorial/inputoutput.html#methods-of-file-objects (Tôi không phải là một trong những downvoting ở đây) – Jacob

+0

nhưng có ví dụ làm thế nào để đọc tập tin từng dòng, không phải là số – kravemir

+0

Câu hỏi của bạn bỏ lỡ cả mô tả rõ ràng về nội dung tệp và kết quả mong muốn. – mac

Trả lời

62

Giả sử bạn không có khoảng trắng không liên quan:

with open('file') as f: 
    w, h = [int(x) for x in next(f).split()] # read first line 
    array = [] 
    for line in f: # read rest of lines 
     array.append([int(x) for x in line.split()]) 

Bạn có thể ngưng tụ cuối cùng cho vòng lặp vào một danh sách hiểu lồng nhau:

with open('file') as f: 
    w, h = [int(x) for x in next(f).split()] 
    array = [[int(x) for x in line.split()] for line in f] 
+3

không phải là giá trị được lưu trữ dưới dạng chuỗi không? – ascobol

+1

Có, tôi cho rằng tôi nên cập nhật câu trả lời của mình. – zeekay

+0

Tôi nghĩ rằng đây là giải pháp ổn, nhưng tôi luôn do dự khi lặp lại và nối thêm ... IMO thường gọn gàng hơn và dễ đọc hơn để làm việc với các trình tạo danh sách, nơi bạn có thể thực hiện cả hai thao tác đơn lẻ và không có luồng -kết cấu điều khiển như vòng lặp 'for'. –

11

Đối với tôi loại vấn đề dường như đơn giản là những gì Python là tất cả về. Đặc biệt là nếu bạn đang đến từ một ngôn ngữ như C++, nơi phân tích văn bản đơn giản có thể là một cơn đau ở mông, bạn sẽ thực sự đánh giá cao giải pháp đơn vị chức năng khôn ngoan mà python có thể cung cấp cho bạn. Tôi muốn giữ cho nó thực sự đơn giản với một vài chức năng được xây dựng trong và một số biểu thức máy phát điện.

Bạn cần open(name, mode), myfile.readlines(), mystring.split(), int(myval) và sau đó có thể bạn sẽ muốn sử dụng một vài máy phát điện để ghép tất cả chúng lại với nhau theo cách nhiệt tình.

# This opens a handle to your file, in 'r' read mode 
file_handle = open('mynumbers.txt', 'r') 
# Read in all the lines of your file into a list of lines 
lines_list = file_handle.readlines() 
# Extract dimensions from first line. Cast values to integers from strings. 
cols, rows = (int(val) for val in lines_list[0].split()) 
# Do a double-nested list comprehension to get the rest of the data into your matrix 
my_data = [[int(val) for val in line.split()] for line in lines_list[1:]] 

Tra cứu biểu thức máy phát here. Chúng thực sự có thể đơn giản hóa mã của bạn thành các đơn vị chức năng rời rạc! Hãy tưởng tượng làm điều tương tự trong 4 dòng trong C++ ... Nó sẽ là một con quái vật. Đặc biệt là danh sách máy phát điện, khi tôi là tôi C++ chàng tôi luôn luôn muốn tôi đã có một cái gì đó như thế, và tôi thường sẽ kết thúc xây dựng các chức năng tùy chỉnh để xây dựng mỗi loại mảng tôi muốn.

+0

Tôi không nghĩ rằng công trình này. 'cols, rows = (int (val) cho val trong '4 3 \ n')' không làm những gì bạn muốn. Tương tự cho '[int (val) cho val trong dòng]' bởi vì 'dòng' sẽ là một cái gì đó như' '1 2 3 4 \ n'' –

+0

@ Jason: Vâng xin lỗi có một vài lỗi trong mã ban đầu của tôi, nhưng ý chính là đúng. Đã sửa ở trên. Tôi đoán đó là những gì phát triển lặp đi lặp lại là dành cho! :) –

+1

Trong trường hợp tầm thường OP đề cập đến, phiên bản C++, trong khi hơi dài hơn, sẽ không phải là "một con quái vật" như bạn nói. Bạn sẽ sử dụng fscanf() hoặc các luồng và vector > (hoặc thậm chí int [] []). Và C++ sẽ cung cấp khả năng kiểm soát nhiều hơn đối với việc quản lý bộ nhớ trong khi đọc và phân tích cú pháp tệp. – dolphin

3

Không chắc chắn tại sao bạn cần w, h. Nếu những giá trị này được thực sự cần thiết và có nghĩa là số chỉ quy định các hàng và cols cần được đọc hơn bạn có thể thử như sau:

output = [] 
with open(r'c:\file.txt', 'r') as f: 
    w, h = map(int, f.readline().split()) 
    tmp = [] 
    for i, line in enumerate(f): 
     if i == h: 
      break 
     tmp.append(map(int, line.split()[:w])) 
    output.append(tmp) 
+1

Cách tiếp cận thú vị để bao gồm dữ liệu tiêu đề là tốt, tôi thậm chí không nghĩ về điều đó. 1 cho đầy đủ ... nhưng nó là một chút dài/khó đọc :) –

+1

Thanx) Tôi đã tạo ra giải pháp mở rộng mà lặp dòng theo dòng và tạo danh sách các danh sách cho tất cả các lần xuất hiện của w, h. Tuy nhiên câu trả lời hay nhất đã được chọn))) –

-2

đang làm việc với cả hai python2 (ví dụ Python 2.7.10) và python3 (ví dụ Python 3.6.4)

with open('in.txt') as f: 
    rows,cols=np.fromfile(f, dtype=int, count=2, sep=" ") 
    data = np.fromfile(f, dtype=int, count=cols*rows, sep=" ").reshape((rows,cols)) 

cách khác: đang làm việc với cả hai python2 (ví dụ Python 2.7.10) và python3 (ví dụ Python 3.6.4), cũng cho ma trận phức tạp xem ví dụ dưới đây (chỉ thay đổi int đến complex)

with open('in.txt') as f: 
    data = [] 
    cols,rows=list(map(int, f.readline().split())) 
    for i in range(0, rows): 
     data.append(list(map(int, f.readline().split()[:cols]))) 
print (data) 

tôi cập nhật mã, phương pháp này đang làm việc cho bất kỳ số lượng ma trận và bất kỳ loại ma trận (int, complex, float) trong tập tin ban đầu in.txt.

Chương trình này mang lại phép nhân ma trận dưới dạng ứng dụng.Đang làm việc với python2, để làm việc với python3 làm những điều sau đây thay đổi

print to print() 

print "%7g" %a[i,j], to  print ("%7g" %a[i,j],end="") 

kịch bản:

import numpy as np 

def printMatrix(a): 
    print ("Matrix["+("%d" %a.shape[0])+"]["+("%d" %a.shape[1])+"]") 
    rows = a.shape[0] 
    cols = a.shape[1] 
    for i in range(0,rows): 
     for j in range(0,cols): 
     print "%7g" %a[i,j], 
     print 
    print  

def readMatrixFile(FileName): 
    rows,cols=np.fromfile(FileName, dtype=int, count=2, sep=" ") 
    a = np.fromfile(FileName, dtype=float, count=rows*cols, sep=" ").reshape((rows,cols)) 
    return a 

def readMatrixFileComplex(FileName): 
    data = [] 
    rows,cols=list(map(int, FileName.readline().split())) 
    for i in range(0, rows): 
     data.append(list(map(complex, FileName.readline().split()[:cols]))) 
    a = np.array(data) 
    return a 

f = open('in.txt') 
a=readMatrixFile(f) 
printMatrix(a) 
b=readMatrixFile(f) 
printMatrix(b) 
a1=readMatrixFile(f) 
printMatrix(a1) 
b1=readMatrixFile(f) 
printMatrix(b1) 
f.close() 

print ("matrix multiplication") 
c = np.dot(a,b) 
printMatrix(c) 
c1 = np.dot(a1,b1) 
printMatrix(c1) 

with open('complex_in.txt') as fid: 
    a2=readMatrixFileComplex(fid) 
    print(a2) 
    b2=readMatrixFileComplex(fid) 
    print(b2) 

print ("complex matrix multiplication") 
c2 = np.dot(a2,b2) 
print(c2) 
print ("real part of complex matrix") 
printMatrix(c2.real) 
print ("imaginary part of complex matrix") 
printMatrix(c2.imag) 

như tập tin đầu vào tôi mất in.txt:

4 4 
1 1 1 1 
2 4 8 16 
3 9 27 81 
4 16 64 256 
4 3 
4.02 -3.0 4.0 
-13.0 19.0 -7.0 
3.0 -2.0 7.0 
-1.0 1.0 -1.0 
3 4 
1 2 -2 0 
-3 4 7 2 
6 0 3 1 
4 2 
-1 3 
0 9 
1 -11 
4 -5 

complex_in.txt

3 4 
1+1j 2+2j -2-2j 0+0j 
-3-3j 4+4j 7+7j 2+2j 
6+6j 0+0j 3+3j 1+1j 
4 2 
-1-1j 3+3j 
0+0j 9+9j 
1+1j -11-11j 
4+4j -5-5j 

và giao diện đầu ra như:

Matrix[4][4] 
    1  1  1  1 
    2  4  8  16 
    3  9  27  81 
    4  16  64 256 

Matrix[4][3] 
    4.02  -3  4 
    -13  19  -7 
    3  -2  7 
    -1  1  -1 

Matrix[3][4] 
    1  2  -2  0 
    -3  4  7  2 
    6  0  3  1 

Matrix[4][2] 
    -1  3 
    0  9 
    1 -11 
    4  -5 

matrix multiplication 
Matrix[4][3] 
    -6.98  15  3 
-35.96  70  20 
-104.94  189  57 
-255.92  420  96 

Matrix[3][2] 
    -3  43 
    18 -60 
    1 -20 

[[ 1.+1.j 2.+2.j -2.-2.j 0.+0.j] 
[-3.-3.j 4.+4.j 7.+7.j 2.+2.j] 
[ 6.+6.j 0.+0.j 3.+3.j 1.+1.j]] 
[[ -1. -1.j 3. +3.j] 
[ 0. +0.j 9. +9.j] 
[ 1. +1.j -11.-11.j] 
[ 4. +4.j -5. -5.j]] 
complex matrix multiplication 
[[ 0. -6.j 0. +86.j] 
[ 0. +36.j 0.-120.j] 
[ 0. +2.j 0. -40.j]] 
real part of complex matrix 
Matrix[3][2] 
     0  0 
     0  0 
     0  0 

imaginary part of complex matrix 
Matrix[3][2] 
    -6  86 
    36 -120 
     2  -40 
Các vấn đề liên quan