2012-06-15 10 views
18

Tôi đang cố gắng phân tích cú pháp tệp được phân cách bằng tab bằng Python, trong đó một số được đặt k tab ngoài phần đầu của hàng, nên được đặt vào mảng thứ k.phân tích cú pháp tệp được phân tách bằng tab bằng Python

Có chức năng tích hợp để thực hiện việc này hay cách tốt hơn, ngoài việc đọc từng dòng và thực hiện xử lý rõ ràng một giải pháp ngây thơ sẽ thực hiện?

+0

đôi khi dễ quên, nhưng thông thường phải chấp nhận câu trả lời cho câu hỏi của bạn .. –

+0

@Bob đừng để chúng tôi treo. – ruipacheco

Trả lời

3

Như thế này:

>>> s='1\t2\t3\t4\t5' 
>>> [x for x in s.split('\t')] 
['1', '2', '3', '4', '5'] 

Đối với một tập tin:

# create test file: 
>>> with open('tabs.txt','w') as o: 
... s='\n'.join(['\t'.join(map(str,range(i,i+10))) for i in [0,10,20,30]]) 
... print >>o, s 

#read that file: 
>>> with open('tabs.txt','r') as f: 
... LoL=[x.strip().split('\t') for x in f] 
... 
>>> LoL 
[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], 
['10', '11', '12', '13', '14', '15', '16', '17', '18', '19'], 
['20', '21', '22', '23', '24', '25', '26', '27', '28', '29'], 
['30', '31', '32', '33', '34', '35', '36', '37', '38', '39']] 
>>> LoL[2][3] 
23 

Nếu bạn muốn đầu vào hoán:

>>> with open('tabs.txt','r') as f: 
... LoT=zip(*(line.strip().split('\t') for line in f)) 
... 
>>> LoT[2][3] 
'32' 

Hoặc (vẫn tốt hơn) sử dụng các mô-đun csv trong bản phân phối mặc định ...

+0

Trong Python, tạo một danh sách trống và sau đó thêm các giá trị là một mẫu chống. Đó là những gì mà danh sách hiểu được. –

+0

@Lattyware: Cá nhân tôi không tìm thấy hình thức đầu tiên khó đọc, nhưng bạn đúng - một danh sách lồng nhau có thể hiểu được nhiều hơn Pythonic. Đã chỉnh sửa. – dawg

+0

@drewk: '[x.split ('\ t') cho f.split ('\ n')]' không có ý nghĩa. Không có đối tượng 'x' và tệp nào không có phương thức' split() '. – martineau

40

Bạn có thể sử dụng the csv module để phân tích cú pháp các tệp có giá trị riêng biệt trong tab.

import csv 

with open("tab-separated-values") as tsv: 
    for line in csv.reader(tsv, dialect="excel-tab"): #You can also use delimiter="\t" rather than giving a dialect. 
     ... 

Trường hợp line là danh sách các giá trị trên hàng hiện tại cho mỗi lần lặp lại.

Edit: Theo gợi ý dưới đây, nếu bạn muốn đọc theo cột, và không phải bởi hàng, sau đó là điều tốt nhất để làm là sử dụng zip() dựng sẵn:

with open("tab-separated-values") as tsv: 
    for column in zip(*[line for line in csv.reader(tsv, dialect="excel-tab")]): 
     ... 
+0

bất cứ khi nào một phần tử bị thiếu có hai tab liên tiếp. công việc vừa ý? – Bob

+3

@Bob Tại sao bạn không thử và xem? (Nhưng có, nó sẽ). –

+3

@Lattyware: Việc bạn sử dụng "tệp" làm tên biến là không có ...;) – martineau

7

Tôi không nghĩ rằng bất kỳ câu trả lời hiện tại thực sự làm những gì bạn nói bạn muốn.

Vì vậy, đây là quan điểm của tôi:

nói đó là những giá trị tách biệt bởi tab trong tập tin đầu vào của bạn:

1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
16 17 18 19 20 

thì đây:

with open("tab-separated-values.txt") as input: 
    print zip(*(line.strip().split('\t') for line in input)) 

sẽ tạo ra những điều sau đây:

[('1', '6', '11', '16'), 
('2', '7', '12', '17'), 
('3', '8', '13', '18'), 
('4', '9', '14', '19'), 
('5', '10', '15', '20')] 

Như bạn có thể thấy, nó đặt phần tử thứ k của mỗi hàng vào mảng thứ k.