Python - 如果源是文件,则Sum不在列表推导语法中工作

时间:2012-04-11 09:17:17

标签: python sum list-comprehension

我是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,则可以总结任何迭代。

任何启蒙都会非常感激。 :)

3 个答案:

答案 0 :(得分: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()

因为我们将得到一个包含整个事物的字符串。在这种情况下,我们可以使用with open("words.txt") as lines: sum(1 for line in lines for word in line.split() if "e" not in word) 将行拆分为单词。

E.g:

{{1}}

答案 1 :(得分:1)

我刚刚试过这个,这样可行,所以它可能与你的文件格式有关:

me@pc:~/Desktop$ cat > words.txt
app
noot
mies
wim
zus
jet
me@ps:~/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

答案 2 :(得分: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

<强>更新

我发布了我提出的解决方案,以防其他人遇到同样的问题。

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)