2012-04-11 34 views
2

我是Python的新手,我正在學習列表理解。Python - 如果源是文件,則不能在列表解析語法中工作

我試圖做的是下面的代碼轉換成列表解析:

def words_without_e(): 
    count = 0 

    words = open('words.txt') 
    for word in words: 
     if word.find('e') == -1: 
      count += 1 
    words.close() 

    return count 

這裏是我的愚蠢的嘗試:

words = open('words.txt') 
print sum([1 for word in words if word.find('e') == -1]) 

但遺憾的是它不工作。我希望得到答案是37641,但我越來越0 :(

我試圖創建另一個代碼做同樣的事情,但文件作爲來源,而不是,我用了一個清單:

def test(): 
    words = ['hello', 'world', 'ciao'] 
    return sum([1 for word in words if word.find('e') == -1]) 

和它的作品。

我看到這個「相當」類似SO post並試圖將代碼貼有return len([word for word in words if len(word) >= 2 and word[0] == word[-1]])。它的工作原理,如果源是一個硬編碼的列表,但如果來源是外部文件失敗。

現在,我的問題是,確實sum只適用於列表和元組?如果我正確理解docs,則可以總結任何迭代。

任何啓發將非常感激。 :)

+2

你的文件格式如何,每行是否有一個字?你的嘗試似乎對我有效...... – jamylak 2012-04-11 09:22:53

+0

@jamylak是的,它的格式是這樣的。 – 2012-04-11 09:24:42

+3

當你說它不起作用時,會發生什麼?它打印什麼? – mikej 2012-04-11 09:27:39

回答

7

最簡單的辦法是這樣的:

with open("words.txt") as words: 
    sum(1 for word in words if "e" not in word) 

正如你所看到的,sum不與任何迭代器的工作 - 在這裏我使用一個生成器表達式。

而不是做word.find('e') == -1我們可以做"e" not in word這是更好的閱讀和工作,因爲字符串可迭代本身和支持__contains__

我也使用with語句來打開文件 - 這比手動打開和關閉它們更好,因爲它可以爲您處理這些事情,並且也可以正確處理異常。

但是我想說明一下,你的例子適用於我。我的猜測是你的文件是空格或逗號分隔,但循環通過文件返回行。

我的測試文件:

bob 
bill 
james 
test 
something 
no 

此,例如,將無法正常工作:

bob bill james test something no 

正如我們將得到一個包含整個事情一個字符串。在這種情況下,我們可以使用str.split()將行分成單詞。

E.G:

with open("words.txt") as lines: 
    sum(1 for line in lines for word in line.split() if "e" not in word) 
+1

適用於'sum(如果「e」不在單詞中則用於單詞中的單詞)''。 – eumiro 2012-04-11 09:25:12

+0

@eumiro我讓一對額外的支架在那裏滑動。 – 2012-04-11 09:26:53

+0

我同意,你的代碼比我的可讀性更強。 :)你認爲這個問題存在於word.find('e')== -1中,而不是像我第一次猜到的那樣在文件本身中? – 2012-04-11 09:27:32

1

我只是嘗試這樣做,那工作,所以它可能有一些跟你的文件是如何被格式化:

[email protected]:~/Desktop$ cat > words.txt 
app 
noot 
mies 
wim 
zus 
jet 
[email protected]:~/Desktop$ python 
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> sum(1 for word in open('words.txt') if 'e' not in word) 
4 
0

好。我試過@Lattyware寫的代碼,它工作正常。我想我已經找到了罪魁禍首,但我不明白爲什麼它會這樣。我想這將是另一個問題。 :)

def count_words(): 
    with open("words.txt") as words: 
     print sum(1 for word in words) 
     print sum(1 for word in words if "e" not in word) 


>>> count_words() 
113809 
0 

但是當我註釋掉第一個打印語句時,它顯示正確的答案。

>>> count_words() 
37641 

UPDATE:

我張貼,我想出了以防萬一別人遇到同樣的問題的解決方案。

def count_words(): 
    total = 0 
    wordsWithoutE = 0 

    with open("words.txt") as words: 
     for word in words: 
      if 'e' not in word: 
       wordsWithoutE += 1 

      total += 1 

    return (total, wordsWithoutE) 


    >>> print count_words() 
    (113809, 37641) 
+6

這是因爲該文件是一個流;一旦你迭代了一次(通過第一個'sum'),你現在在流的末尾,並且試圖再次迭代它將不會再讀取任何數據。 – 2012-04-11 09:56:53

+3

這裏的解決方案是做''stored = list(words)''然後從那裏開始工作。該列表可以重複一次又一次。 – 2012-04-11 10:32:54

相關問題