2009-12-02 27 views

Trả lời

14

Bạn có thể cố gắng sử dụng liệt kê,

http://docs.python.org/tutorial/datastructures.html#looping-techniques

lines = open('wordprob.txt','r').readlines() 
words = open('StdWord.txt','r').readlines() 
for i,line in enumerate(lines): 
     v = [eval(s) for s in line.split()] 
     if v[0] > v[1]: 
       print words[i].strip() 
+5

Tôi không thích giải pháp này vì nó đọc tất cả dữ liệu vào RAM. Điều này là không sao miễn là dữ liệu phù hợp với RAM, và nó rất đơn giản, nhưng tôi thích các giải pháp chung hoạt động trên bất kỳ tập dữ liệu kích thước nào. – steveha

1

Hãy xem enumerate:

>>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): 
...  print i, season 
0 Spring 
1 Summer 
2 Fall 
3 Winter 
5

Trong enumerate chung là một giải pháp tốt. Trong trường hợp này, bạn có thể làm điều gì đó như:

lines = open('wordprob.txt','r').readlines() 
words = open('StdWord.txt','r').readlines() 
for word, line in zip(words, lines): 
    v = [eval(s) for s in line.split()] 
    if v[0] > v[1]: 
      print word.strip(), 
+4

'zip()' là một cách tốt để lặp lại với hai thứ. Tuy nhiên, trong Python 2.x, nó sẽ xây dựng một danh sách với tất cả các giá trị, do đó, điều này sẽ mất rất nhiều bộ nhớ. Bạn có thể nhận được cùng một hiệu ứng với 'itertools.izip()', trả về một trình lặp mà trả về các giá trị một tại một thời điểm. Bạn có thể 'nhập itertools' và sau đó làm điều này:' cho từ, dòng trong itertools.izip (mở ('wordprob.txt'), mở ('StdWord.txt')): ' – steveha

+0

@steveha: Ngoài ra, bạn chọn trong các phiên bản Py3 của các hàm bằng cách thực hiện 'từ bản đồ nhập khẩu trong tương lai_builtins, bộ lọc, zip' và bạn thay thế các phiên bản Py2 bằng các phiên bản dựa trên vòng lặp Py3. – ShadowRanger

20

Có vẻ như bạn không quan tâm giá trị của i là gì. Bạn chỉ đang sử dụng nó như một cách để ghép nối các lineswords. Do đó, tôi khuyên bạn nên đọc từng dòng một, và đồng thời đọc một từ. Sau đó, họ sẽ phù hợp.

Ngoài ra, khi bạn sử dụng .readlines() bạn đọc tất cả các đầu vào cùng một lúc vào bộ nhớ. Đối với đầu vào lớn, điều này sẽ chậm. Đối với mã đơn giản này, một dòng tại một thời điểm là tất cả những gì bạn cần. Đối tượng tệp được trả về bởi open() có thể hoạt động như một trình lặp mà trả về một dòng tại một thời điểm.

Nếu có thể, bạn nên tránh sử dụng eval(). Trong một bài tập đơn giản mà bạn biết dữ liệu đầu vào là gì, nó khá an toàn, nhưng nếu bạn lấy dữ liệu từ các nguồn bên ngoài, việc sử dụng eval() có thể cho phép máy tính của bạn bị tấn công. Xem this page để biết thêm thông tin. Tôi sẽ viết mã ví dụ của tôi để giả định rằng bạn đang sử dụng eval() để chuyển văn bản thành giá trị float. float() cũng sẽ hoạt động trên một giá trị chuỗi số nguyên: float('3') sẽ trả lại 3.0.

Ngoài ra, có vẻ như các dòng nhập chỉ có thể có hai giá trị. Nếu một dòng có giá trị thừa, mã của bạn sẽ không phát hiện tình trạng này. Chúng ta có thể thay đổi mã để giải nén một cách rõ ràng hai giá trị từ đường phân tách, và sau đó nếu có nhiều hơn hai giá trị, Python sẽ tăng một ngoại lệ. Thêm vào đó, mã sẽ đẹp hơn một chút để đọc.

Vì vậy, đây là viết lại đề nghị của tôi về ví dụ này:

lines = open('wordprob.txt','rt') 
words = open('StdWord.txt','rt') 

for line in lines: 
    word = words.next().strip() # in Python 3: word = next(words).strip() 
    a, b = [float(s) for s in line.split()] 
    if a > b: 
     print word, # in Python 3: print(word + ' ', end='') 

EDIT: Và đây là giải pháp tương tự, nhưng sử dụng izip().

import itertools 
lines = open('wordprob.txt','rt') 
words = open('StdWord.txt','rt') 

# in Python 3, just use zip() instead of izip() 
for line, word in itertools.izip(lines, words): 
    word = word.strip() 
    a, b = [float(s) for s in line.split()] 
    if a > b: 
     print word, # in Python 3: print(word + ' ', end='') 

Trong Python 3, được xây dựng trong zip() trả về một iterator, vì vậy bạn chỉ có thể sử dụng và không cần phải import itertools.

EDIT: Cách tốt nhất là sử dụng câu lệnh with để đảm bảo các tệp được đóng đúng cách, bất kể là gì. Trong các phiên bản gần đây của Python bạn có thể có nhiều câu lệnh, và tôi sẽ làm điều đó trong giải pháp của mình.Ngoài ra, chúng tôi có thể giải nén một biểu thức máy phát điện dễ dàng như chúng ta có thể giải nén một danh sách, vì vậy tôi đã thay đổi dòng đặt a, b để sử dụng biểu thức trình tạo; sẽ nhanh hơn một chút. Và chúng tôi không cần phải loại bỏ word trừ khi chúng tôi sẽ sử dụng nó. Đặt các thay đổi với nhau để nhận được:

from itertools import izip 

with open('wordprob.txt','rt') as lines, open('StdWord.txt','rt') as words: 
    # in Python 3, just use zip() instead of izip() 
    for line, word in izip(lines, words): 
     a, b = (float(s) for s in line.split()) 
     if a > b: 
      print word.strip(), # in Python 3: print(word.strip() + ' ', end='') 
+0

cảm ơn bạn đã có ý kiến ​​quý giá! –

+0

Bạn rất hoan nghênh! :-) – steveha

Các vấn đề liên quan