今天我们来学习总结下Python之禅和他朋友们的第三题,这两天一直有事情没跟上大家的学习学习节奏,现在来学习一下的军哥的代码Python之禅,搞清楚每一行代码的意思
题目
统计一个文件中每个单词出现的次数,列出出现频率最多的5个单词。
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
在学习前我们需要了解一下几点知识:
- Python的i\o操作
- 列表解析、sort()方法、sorted()函数
- 字典Dict操作
- 正则表达式re
- lambda表达式
- Counter
- assert断言
Python的i\o操作
I\O:input\output
这里推荐网上两个参考教程,一个是廖雪峰老师的,另一个是菜鸟教程
参考链接
参考链接
读写文件
#r:表示读,
#w:表示输出生成并打开文件
#a:文件尾部追加内容而打开文件
#文件处理模式字符串尾部加上b可以进行二进制数据处理,Example:'rb'
#加上‘+’:同时为输入和输出打开文件
>>> f = open('myfile.txt', 'w') #
>>> f.write('hello world!', 'w') #在文本内写入“hello world!”
>>> 12
>>> f.write('hello treehl!', 'w') #在文本内写入“hello world!”
>>> 12
>>> f.close() #关闭文本
>>> f = open('myfile.txt')
>>> f.readline() #读取一行
>>> 'hello world!'
>>> f.readline()
>>> 'hello treehl!'
使用for循环打印文本:
>>> for line in open('myfile'):
print(line)
>>> data = open('data.bin', 'rb')
>>> print(data.read())
>>> b' \x00\x00\x07spam\x00\x08'
由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,Python引入了with语句来自动帮我们调用close()方法
>>> with open('myfile.txt', 'r') as f: #r:表示读,w:
print(f.read())
>>> hello world!
hello treehl!
列表解析、sort()方法、sorted()函数
在军哥的代码中有一行使用了列表解析式,我们正好学习下
words = [s.lower() for s in re.findall("\w+", data)]
1. 列表解析
我们先看一下普通的生成列表
>>> res =[]
>>> for x in 'spam':
res.append(x * 4)
>>> res
['ssss', 'pppp', 'aaaa', 'mmmm']
我们再来看一下列表解析的代码
>>> res = [x * 4 for x in 'spam']
>>> res
>>> ['ssss', 'pppp', 'aaaa', 'mmmm']
生成列表res的方式包含三行代码,而用列表解析只需要一行,非常简单!我们来分析下列表解析,首先制定列表名称,如res,接着定义一个表达式 x * 4 ,最后再编写一个for 循环 for x in 'spam'
2. sort()方法
sort()方法:原地对列表进行永久性排序,而且已递增的顺序进行排序
>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> cars.sort()
>>> print(cars)
['audi', 'bmw', 'honda', 'tesla']
#
>>> print(cars) #使用sort()方法后无法再回到原来的排序
['audi', 'bmw', 'honda', 'tesla']
我们可以在列表中添加reverse参数使列表反转
>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> cars.sort(reverse=True)
>>> print(cars)
['tesla', 'honda', 'bmw', 'audi']
sorted()函数
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
sorted()对列表进行临时性排序,并且同样也可以向sorted函数传递reverse参数
>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> print(cars)
['bmw', 'audi', 'tesla', 'honda']
>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> print(sorted(cars))
['audi', 'bmw', 'honda', 'tesla']
>>> print(cars) #调用函数sorted()列表顺序并没有发生改变
['bmw', 'audi', 'tesla', 'honda']
>>>print(sorted(cars, reverse=True))
['tesla', 'honda', 'bmw', 'audi']
字典操作
这里就不总结字典使用方法了,可以参考廖雪峰老师的Python教程
我们看到军哥的代码中使用了dict中的get方法
self.mapping[word] = self.mapping.get(word, 0) + 1
字典以“键:值(key:value)”对形式表达
D = {'spam': 2, 'eggs': 3}
字典values和items方法分别返回字典的key值列表和(key, value)对元组
>>> D = {'spam': 2, 'hams': 1, 'eggs': 3}
>>> D.keys()
dict_keys(['spam', 'hams', 'eggs'])
>>> D.values()
dict_values([2, 1, 3])
>>> D.items()
dict_items([('spam', 2), ('hams', 1), ('eggs', 3)])
这里需要重点看下
读取不存在的键会报错,然而通过get()方法能够返回默认的值(None或用户定义的默认值),这是为了避免missing-key错误而填入默认值的一个方法:
>>> D.get('spam')
2
>>> print(D.get('toast'))
None
>>> D.get('toast', 88)
88
正则表达式re
学习正则还是有点繁琐的,不多废话附上参考
参考链接
参考链接
"\w+"
\w:匹配[A-Z,a-z,0-9];
+ :匹配前一个字符0次或无限次
lambda表达式
lambda表达式创建了一个之后能够调用的函数,但是它返回了一个函数而不是将这个函数赋值给一个变量名
- lambda能够出现在Python语法不允许def出现的地方
- lambda的主体是一个单个的表达式,而不是一个代码块
现在我们看一下def和lambda表达式的区别:
>>> def func(x, y, z):
return x + Y + z
>>> func(2, 3, 4)
9
>>> f = lambda x, y, z: x + y +z
>>> f(2, 3, 4)
9
来看个复杂点的
>>> def knights():
title = 'Sir'
action = (lambda x: title + ' ' + x)
return action
>>> act = knights()
>>> act('treehl')
'Sir treehl'
counter
参考链接
这里也谢谢九二同学的分享
assert断言
凡是用print()来辅助查看的地方,都可以用断言(assert)来替代,假如断言失败,就会抛出错误
这里分享下参考链接,今天翻了Python学习手册的assert,相比廖雪峰老师的教程Python学习手册的assert显得有点难懂。。。。。。。
参考链接
最后附上军哥的代码
# _*_ coding:utf-8 _*_
import io
import re
class Counter:
def __init__(self, path):
'''
:param path: 文件路径
'''
self.mapping = dict()
#使用io.open可以添加encoding参数
with io.open(path, encoding='utf-8') as f:
data = f.read()
#使用列表解析式
#findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags]):
#搜索string,以列表形式返回全部能匹配的子串
#\w匹配[A-Z,a-z,0-9];+ 匹配前一个字符0次或无限次,data为读取的文件
#Python lower() 方法转换字符串中所有大写字符为小写
words = [s.lower() for s in re.findall('\w+', data)]
for word in words:
#当key不存在时通过get方法返回默认值
self.mapping[word] = self.mapping.get(word, 0) + 1
def most_common(self, n):
#使用assert断言
assert n >0, 'n should be larger than 0'
#sort()方法对列表进行永久性排列
#sorted()函数对列表进行临时排序
#reverse=True使列表反转
#字典items()返回(key, value)对元组
#使用lambda表达式
return sorted(self.mapping.items(), key=lambda item:item[1], reverse=True)[:n]
if __name__ == '__main__':
#创建实例,调用most_common方法,打印排名前五的单词
most_common_5 = Counter('importthis.txt').most_common(5)
for item in most_common_5:
print(item)
欢迎大家访问我的博客Treehl的博客
网友评论