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

Ann*_*ang 3 python list-comprehension sum

我是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
Run Code Online (Sandbox Code Playgroud)

这是我的微弱尝试:

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

但不幸的是它没有用.我期望得到的答案是37641,但我得到0. :(

我尝试创建另一个代码做同样的事情但不是文件作为源,我使用了一个列表:

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

它有效.

我看到了这个"非常"类似的SO 帖子,并尝试了那里发布的代码return len([word for word in words if len(word) >= 2 and word[0] == word[-1]]).如果源是硬编码列表,则它可以工作但如果源是外部文件则会失败.

现在,我的问题是,是否sum仅适用于列表和元组?如果我理解正确的文档,任何可迭代都可以总结.

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

Gar*_*tty 7

最简单的解决方案是:

with open("words.txt") as words:
  sum(1 for word in words if "e" not in word)
Run Code Online (Sandbox Code Playgroud)

如您所见,sum可以使用任何迭代器 - 这里我使用的是生成器表达式.

而不是做word.find('e') == -1我们可以只做"e" not in word更好的阅读和工作,因为字符串可以自己迭代和支持__contains__.

我也使用该with语句来打开文件 - 这比在处理这些事情时手动打开和关闭它们更好,并且也正确处理异常.

不过我想注意一下,你的例子适合我.我的猜测是你的文件是空格或逗号分隔,但循环文件返回行.

我的测试文件:

bob
bill
james
test
something
no
Run Code Online (Sandbox Code Playgroud)

例如,这不起作用:

bob bill james test something no
Run Code Online (Sandbox Code Playgroud)

因为我们将得到一个包含整个事物的字符串.在这种情况下,我们可以使用str.split()将行拆分为单词.

例如:

with open("words.txt") as lines:
    sum(1 for line in lines for word in line.split() if "e" not in word)
Run Code Online (Sandbox Code Playgroud)