2012-05-02 15 views
2

我的問題是,如果除了下面還有其他方法來一次遍歷文件中的一個字符?從python的文件中讀取單個字符?

with open(filename) as f: 
    while True: 
    c = f.read(1) 
    if not c: 
     print "End of file" 
     break 
    print "Read a character:", c 

由於沒有檢查是否有東西讀起來就像Java中的功能,還有什麼其他的方法有哪些。另外,在這個例子中,變量c到達文件末尾時會是什麼?感謝任何人的幫助。

+0

這種方式有什麼問題? – Keith

+0

是的,它是「重複」的代碼,但它不是同一個問題。如果你真的很想讀另一個問題,他得到了他的答案,而我想知道我一直在嘗試的其他方法。謝謝你指出,雖然... – Andy

回答

7

這是一種方式:

with open(filename) as f: 
    for line in f: 
     for c in line: 
      pass 

或者是什麼樣?

with open(filename) as f: 
    for c in f.read(): 
     pass 
+2

+1。第一種解決方案通常更好,因爲後者可能會導致非常大的文件(內存不足)出現問題。 –

+0

啊,我不認爲你可以在Python for循環(第二代碼)中做到這一點。謝謝。 – Andy

+1

@Lattyware:第一個也是一樣,因爲該文件可能包含非常長的行:P – orlp

3

這裏有文件對象的其他方法:

'關閉', '的fileno', '沖洗', 'isatty', '換行', '下一步', '讀', 'readinto', '的ReadLine', 'readlines方法', '求', 'softspace', '告訴', '截斷', '寫', 'writelines', 'xreadlines'

你可以在documentation中閱讀。

如果沒有其他內容可讀,變量c將爲空字符串。它評估爲False,因此測試if not c爲True。這表明你在文件的末尾。

+0

@nightcracker以下是問題:「還有什麼其他方法。另外,在這個例子中,當變量c到達文件末尾時變量c是什麼?' – Keith

+0

不夠公平,它回答了這個問題。 – orlp

+0

謝謝您的輸入! – Andy

8

另一種選擇是使用itertools.chain.from_iterable()

import itertools 

with open("test.txt") as f: 
    for c in itertools.chain.from_iterable(f): 
     print(c) 

chain.from_iterable使得返回來自第一迭代元件可迭代給定的迭代,直到它耗盡,然後前進到下一個迭代,直到所有的iterables的已經筋疲力盡了。通常情況下,這是用來展平列表清單,但在這種情況下,它允許您忽略這些行。

這是否真的比嵌套循環更好是另一回事(它會快一點,但這不太可能),但值得一提。

+0

但是,鏈接一個迭代沒有多大意義。在這種情況下只需使用文件對象本身。 – Keith

+1

@Keith它的確如此。他們提供者需要字符,因此該文件是可迭代的行 - 這是可重複使用的字符串。所以這需要可迭代的線條並給出可迭代的字符。 –

+0

Keith:您可以將文件對象看作迭代器上的迭代器,因爲迭代它時會返回字符串(這是可迭代的)。 – orlp

2

一種替代是使用一個發電機:

def blocks(infile, bufsize=1024): 
    while True: 
     try: 
      data=infile.read(bufsize) 
      if data: 
       yield data 
      else: 
       break 
     except IOError as (errno, strerror): 
      print "I/O error({0}): {1}".format(errno, strerror) 
      break 

f=open('somefile.txt','rb') 

for c in blocks(f,1): 
    print c 

與發電機,整個文件未保存在存儲器中和的盤讀取該底層操作系統通常會進行適當的緩衝。

作爲一個生成器,它將像任何其他迭代一樣工作;當文件中沒有更多的字符可讀時它會中斷。