Python每日一題:第三題

今天我們來學(xué)習(xí)總結(jié)下Python之禪和他朋友們的第三題,這兩天一直有事情沒跟上大家的學(xué)習(xí)學(xué)習(xí)節(jié)奏,現(xiàn)在來學(xué)習(xí)一下的軍哥的代碼Python之禪,搞清楚每一行代碼的意思

題目

統(tǒng)計一個文件中每個單詞出現(xiàn)的次數(shù),列出出現(xiàn)頻率最多的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!

在學(xué)習(xí)前我們需要了解一下幾點知識:

  • Python的i\o操作
  • 列表解析、sort()方法、sorted()函數(shù)
  • 字典Dict操作
  • 正則表達(dá)式re
  • lambda表達(dá)式
  • Counter
  • assert斷言

Python的i\o操作

I\O:input\output
這里推薦網(wǎng)上兩個參考教程,一個是廖雪峰老師的,另一個是菜鳥教程
參考鏈接
參考鏈接

讀寫文件

#r:表示讀,
#w:表示輸出生成并打開文件
#a:文件尾部追加內(nèi)容而打開文件
#文件處理模式字符串尾部加上b可以進(jìn)行二進(jìn)制數(shù)據(jù)處理,Example:'rb'
#加上‘+’:同時為輸入和輸出打開文件
>>> f = open('myfile.txt', 'w') #
>>> f.write('hello world!', 'w') #在文本內(nèi)寫入“hello world!”
>>> 12
>>> f.write('hello treehl!', 'w') #在文本內(nèi)寫入“hello world!”
>>> 12
>>> f.close() #關(guān)閉文本
>>> f = open('myfile.txt')
>>> f.readline() #讀取一行
>>> 'hello world!'
>>> f.readline()
>>> 'hello treehl!'
使用for循環(huán)打印文本:
>>> for line in open('myfile'):
        print(line)
>>> data = open('data.bin', 'rb')
>>> print(data.read())
>>> b' \x00\x00\x07spam\x00\x08'        

由于文件讀寫時都有可能產(chǎn)生IOError,一旦出錯,后面的f.close()就不會調(diào)用。所以,Python引入了with語句來自動幫我們調(diào)用close()方法

>>> with open('myfile.txt', 'r') as f: #r:表示讀,w:
        print(f.read())
>>> hello world!
    hello treehl!

列表解析、sort()方法、sorted()函數(shù)

在軍哥的代碼中有一行使用了列表解析式,我們正好學(xué)習(xí)下

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,接著定義一個表達(dá)式 x * 4 ,最后再編寫一個for 循環(huán) for x in 'spam'

2. sort()方法
sort()方法:原地對列表進(jìn)行永久性排序,而且已遞增的順序進(jìn)行排序

>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> cars.sort()
>>> print(cars)
['audi', 'bmw', 'honda', 'tesla']
# 
>>> print(cars) #使用sort()方法后無法再回到原來的排序
['audi', 'bmw', 'honda', 'tesla']

我們可以在列表中添加reverse參數(shù)使列表反轉(zhuǎn)

>>> cars = ['bmw', 'audi', 'tesla', 'honda']
>>> cars.sort(reverse=True)
>>> print(cars)
['tesla', 'honda', 'bmw', 'audi']

sorted()函數(shù)

sort 與 sorted 區(qū)別:
sort 是應(yīng)用在 list 上的方法,sorted 可以對所有可迭代的對象進(jìn)行排序操作。
list 的 sort 方法返回的是對已經(jīng)存在的列表進(jìn)行操作,而內(nèi)建函數(shù) sorted 方法返回的是一個新的 list,而不是在原來的基礎(chǔ)上進(jìn)行的操作。
sorted()對列表進(jìn)行臨時性排序,并且同樣也可以向sorted函數(shù)傳遞reverse參數(shù)

>>> 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) #調(diào)用函數(shù)sorted()列表順序并沒有發(fā)生改變
['bmw', 'audi', 'tesla', 'honda']
>>>print(sorted(cars, reverse=True))
['tesla', 'honda', 'bmw', 'audi']

字典操作

這里就不總結(jié)字典使用方法了,可以參考廖雪峰老師的Python教程
我們看到軍哥的代碼中使用了dict中的get方法

self.mapping[word] = self.mapping.get(word, 0) + 1

字典以“鍵:值(key:value)”對形式表達(dá)

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()方法能夠返回默認(rèn)的值(None或用戶定義的默認(rèn)值),這是為了避免missing-key錯誤而填入默認(rèn)值的一個方法:

>>> D.get('spam')
2
>>> print(D.get('toast'))
None
>>> D.get('toast', 88)
88

正則表達(dá)式re

學(xué)習(xí)正則還是有點繁瑣的,不多廢話附上參考
參考鏈接
參考鏈接

"\w+"
\w:匹配[A-Z,a-z,0-9];
+ :匹配前一個字符0次或無限次

lambda表達(dá)式

lambda表達(dá)式創(chuàng)建了一個之后能夠調(diào)用的函數(shù),但是它返回了一個函數(shù)而不是將這個函數(shù)賦值給一個變量名

  • lambda能夠出現(xiàn)在Python語法不允許def出現(xiàn)的地方
  • lambda的主體是一個單個的表達(dá)式,而不是一個代碼塊

現(xiàn)在我們看一下def和lambda表達(dá)式的區(qū)別:

>>> 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

來看個復(fù)雜點的

>>> def knights():
        title = 'Sir'
        action = (lambda x: title + ' ' + x)
        return action
>>> act = knights()
>>> act('treehl')
'Sir treehl'

counter

參考鏈接
這里也謝謝九二同學(xué)的分享

assert斷言

凡是用print()來輔助查看的地方,都可以用斷言(assert)來替代,假如斷言失敗,就會拋出錯誤
這里分享下參考鏈接,今天翻了Python學(xué)習(xí)手冊的assert,相比廖雪峰老師的教程Python學(xué)習(xí)手冊的assert顯得有點難懂。。。。。。。
參考鏈接

最后附上軍哥的代碼

# _*_ coding:utf-8 _*_
import io
import re

class Counter:
    def __init__(self, path):
        '''

        :param path: 文件路徑
        '''
        self.mapping = dict()
        #使用io.open可以添加encoding參數(shù)
        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() 方法轉(zhuǎn)換字符串中所有大寫字符為小寫
            words = [s.lower() for s in re.findall('\w+', data)]
            for word in words:
                #當(dāng)key不存在時通過get方法返回默認(rèn)值
                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()方法對列表進(jìn)行永久性排列
        #sorted()函數(shù)對列表進(jìn)行臨時排序
        #reverse=True使列表反轉(zhuǎn)
        #字典items()返回(key, value)對元組
        #使用lambda表達(dá)式
        return sorted(self.mapping.items(), key=lambda item:item[1], reverse=True)[:n]

if __name__ == '__main__':
    #創(chuàng)建實例,調(diào)用most_common方法,打印排名前五的單詞
    most_common_5 = Counter('importthis.txt').most_common(5)
    for item in most_common_5:
        print(item)

歡迎大家訪問我的博客Treehl的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容