2012-02-07 35 views
5

Tôi đọc qua một tập tin bằng cách sử dụng vòng lặp for như thế này ...file lặp, kiểm tra dòng sự tồn tại

f = open("somefile.txt") 

for line in f: 
    do stuff 

trừ cho mỗi dòng tôi đọc tôi cần phải thực hiện một mục từ dòng trước nó và đặt nó vào dòng hiện tại. Cách tốt nhất để làm việc này là gì? Có cách nào để đọc dòng tiếp theo hoặc lấy một số mục từ nó mà không đọc nó?

+0

Hoặc bằng cách nào đó tôi có thể kiểm tra xem dòng tiếp theo có tồn tại hay không trước khi đọc nó? –

+0

Bạn có ý gì khi 'đặt nó trong dòng hiện tại' ??? Bạn muốn sửa đổi một dòng ghi trên ổ đĩa cứng với dữ liệu có trong dòng phía trước ?? – eyquem

Trả lời

6

Nếu hiểu biết của tôi là đúng, và bạn muốn làm việc trên mỗi dòng lần lượt, sử dụng một số giá trị từ dòng tiếp theo, đề xuất của tôi sẽ đơn giản là lưu trữ giá trị bạn hiện đang đọc và làm việc trên giá trị cuối cùng. Làm việc ngược lại - last_line là dòng và dòng hiện tại của bạn là dòng tiếp theo.

last_line = None 

with open("somefile.txt") as f: 
    for line in f: 
     if not last_line == None: 
      do_stuff(last_line, extract_needed_part(line)) 
     last_line = line 
do_stuff(last_line) #The final line without anything following it. 

Trong thuật ngữ toán học, thay vì dòng n và dòng n + 1, làm dòng n-1 và dòng n. Hiệu ứng tương tự.

Ưu điểm của phương pháp này là không có nghĩa là tải toàn bộ tệp ngay từ đầu.

+0

Tôi ước tôi có thể bỏ phiếu cho câu trả lời của bạn nhưng tiếc là tôi chưa có 15 danh tiếng. Cảm ơn bạn mặc dù, tôi thấy điều này hữu ích. –

+0

@ user1178682 Bạn có thể chấp nhận câu trả lời của tôi, nếu nó đã giải quyết được vấn đề của bạn: http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 –

3

Nếu tập tin của bạn không phải là lớn, bạn có thể đọc nó vào bộ nhớ và sử dụng nó ở đó:

f = open("somefile.txt") 
lines = f.readlines() 
f.close() 

for index, value in enumerate(lines): 
    # Check if next line exists 
    if index + 1 > len(lines): 
     next_line = lines(index + 1) 
     # do something with line and next_line 

Edit:

Đối với các file lớn, nó sẽ là dễ nhất để chỉ cần nhớ trước đó của bạn dòng:

f = open("somefile.txt") 
previous_line = f.readline() 
for line in f: 
    # Do something with line and previous_line 
    print(line, previous_line) 
    # Save this line for the next iteration 
    previous_line = line 

Có thể có trường hợp cạnh tùy thuộc vào dữ liệu của bạn. Các dòng của bạn luôn theo cặp hoặc bạn chỉ cần một chút thông tin từ dòng tiếp theo trong một số trường hợp nhất định.

Ví dụ: mã này sẽ không làm bất cứ điều gì nếu tệp của bạn chỉ có một dòng.

+0

Vấn đề là các tệp khá lớn, tôi muốn thực hiện việc xử lý mà không phải lưu trữ mọi dòng trong bộ nhớ ban đầu. Tôi đã hy vọng sẽ có một số phương pháp tôi không biết. Đây là một lựa chọn sao lưu tốt nếu tất cả các thất bại khác mặc dù. Cảm ơn vì đã trả lời. –

+0

Trong ví dụ của bạn cho chỉnh sửa của bạn, đó là khá nhiều một lặp lại câu trả lời của tôi, ngoại trừ bạn không sử dụng với (mà bạn nên) và cho việc thực hiện đầu tiên, previous_line và dòng sẽ giống nhau. –

+0

Tôi có một thử, mệnh đề IOException trong mã thực tế của tôi thay vì một với (đối với tính tương thích). Đây là một khái quát hóa hơn, nơi chúng ta có thể giả định tệp tồn tại và sẽ không trả về lỗi nào. Tuy nhiên, sự đồng thuận dường như chỉ đơn giản là gắn liền với dòng trước đó. Nếu đó là cách tốt nhất, tôi sẽ sử dụng nó. –

0

Nếu tập tin của bạn phù hợp trong bộ nhớ, bạn có thể thử một cái gì đó như thế này:

f = open('somefile.txt') 
lines = f.read().splitlines() 

for current_line, next_line in zip(lines, lines[1:]): 
    print current_line 
    print next_line 
    print '-------' 

Đoạn mã trên về cơ bản đọc tất cả các dòng và sử dụng zip để tạo ra một danh sách các hàng có chứa các dòng hiện tại và tiếp theo một.

Edit: Ngoài ra, đối với các file dài, bạn có thể sử dụng itertools thư viện như sau:

import itertools 
f = open('somefile.txt') 
i1, i2 = itertools.tee(f) 
lines = itertools.izip(i1, itertools.islice(i2, 1, None)) 
for current_line, next_line in lines: 
    print current_line 
    print next_line 
    print '-------' 

Trong trường hợp này:

  • itertools.tee được sử dụng để tạo ra hai vòng lặp indenpendent (một cho dòng điện và một cho dòng tiếp theo) sử dụng trình lặp tệp gốc.
  • itertools.slice được sử dụng để bắt đầu trình lặp dòng tiếp theo trong dòng thứ hai.
  • itertools.izip được sử dụng để kết hợp các kết quả của cả hai trình lặp dòng theo dòng trong một bộ.

Chỉnh sửa 2: Theo đề nghị của @eyquem, bạn cũng có thể mở các tập tin hai lần:

import itertools 
f = open('somefile.txt') 
g = open('somefile.txt') 
lines = itertools.izip(f, itertools.islice(g, 1, None)) 
for current_line, next_line in lines: 
    print current_line 
    print next_line 
    print '-------' 
+1

Không cần sử dụng ** tee() **. Chỉ cần định nghĩa một trình xử lý tệp khác: '' g = open ('somefile.txt') '' và làm cho nó di chuyển một dòng phía trước bằng '' g.readline() ''. Sau đó, '' lines = ((f.readline(), dòng) cho dòng trong g) '' – eyquem

+0

@eyquem Cảm ơn bạn đã bình luận. Tôi đã chỉnh sửa câu trả lời để đưa vào nhận xét của bạn. – jcollado

0
with open('somefile.txt') as f, open('somefile.txt') as g: 
    g.readline() 
    lines = ((f.readline(),line) for line in g) 
     for precline,aheadline in lines: 
      # do what you want 
Các vấn đề liên quan