Python中的Try Except

2 投票
4 回答
914 浏览
提问于 2025-04-16 16:04

我想要指定一个文件的路径,打开这个文件并读取里面的数据。然后,我想统计一下字母表中每个字母出现的次数。

根据我了解到的,使用try/except会是个不错的选择。我尽力尝试了,但我只成功统计了程序中字符串里字母的出现次数,而不是文件里的字母。

现在我完全不知道该怎么做了,我的脑袋开始疼了……这是我目前的代码:

import sys
print "Enter the file path:"
thefile = raw_input()
f = open(thefile, "r")
chars = {}
for c in f:
    try:
        chars[c]+=1
    except:
        chars[c]=1
print chars

任何帮助都将非常感谢。谢谢你。

补充说明:我忘了说,现在我得到的结果显示整个文件只有一个字符。这个文件的内容是“abcdefghijklmnopqrstuvwxyz”,而我得到的结果是:{'"abcdefghijklmnopqrstuvwxyz"\n': 1},这显然不对。

4 个回答

1

for c in f: 这行代码是逐行处理你的文件(这是文件对象的for操作的设计目的)。因为你想要逐个字符地处理文件,所以可以把它改成:

data = f.read()
for c in data:

.read() 方法会把整个文件的内容读取到一个字符串中,然后把这个字符串赋值给data,接着for循环就会逐个考虑这个字符串里的每一个字符。

1

你快到了,其实你最重要的一个问题是,你的 c 不是一个字符,而是一整行:在Python中读取文件时,每次得到的是一行。你可以通过添加另一个循环来解决这个问题:

print "Enter the file path:"
thefile = raw_input()
f = open(thefile, "r")
chars = {}
for line in f:
    for c in line:
        try:
            chars[c]+=1
        except:
            chars[c]=1
print chars

(如果你的文件足够小,可以放进内存,读取整个文件到一个字符串中也是可行的,正如其他答案提到的那样。)

虽然在这种情况下这样做是有效的,但直接使用 except: 并不是个好主意,除非你真的想捕捉所有可能的错误。更好的做法是使用 except KeyError:

你想做的事情是很常见的,所以Python有一个字典的方法和数据类型,可以让你完全不需要使用 try/except。你可以看看 这个 setdefault 方法这个 defaultdict 类型。使用这两者中的任何一个,你可以简单地指定缺失的值从0开始。

4

一种稍微优雅一点的方法是这样的:

from __future__ import with_statement

from collections import defaultdict

print "Enter the file path:"
thefile = raw_input()

with open(thefile, "r") as f:
    chars = defaultdict(int)

    for line in f:
        for c in line:
            chars[c] += 1

    print dict(chars)

这个方法使用了一个叫做 defaultdict 的工具,来简化计数的过程。它用了两个循环,确保我们可以逐个读取每个字符,而不需要把整个文件都加载到内存中。同时,它还使用了 with 这个块,确保文件能被正确关闭。

编辑:

如果你想计算字母的直方图,可以使用这个版本:

from __future__ import with_statement

from string import ascii_letters

print "Enter the file path:"
thefile = raw_input()

chars = dict(zip(ascii_letters, [0] * len(ascii_letters)))

with open(thefile, "r") as f:

    for line in f:
        for c in line:
            if c in ascii_letters:
                chars[c] += 1

for c in ascii_letters:
    print "%s: %d" % (c, chars[c])

这个方法使用了一个很方便的 string.ascii_letters 常量,并展示了一种巧妙的方式来使用 zip() 来构建一个空字典。

撰写回答