Python中的Try Except
我想要指定一个文件的路径,打开这个文件并读取里面的数据。然后,我想统计一下字母表中每个字母出现的次数。
根据我了解到的,使用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 个回答
for c in f:
这行代码是逐行处理你的文件(这是文件对象的for
操作的设计目的)。因为你想要逐个字符地处理文件,所以可以把它改成:
data = f.read()
for c in data:
.read()
方法会把整个文件的内容读取到一个字符串中,然后把这个字符串赋值给data
,接着for
循环就会逐个考虑这个字符串里的每一个字符。
你快到了,其实你最重要的一个问题是,你的 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开始。
一种稍微优雅一点的方法是这样的:
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()
来构建一个空字典。