logging、hashlib、collections模块
一、hashlib模塊(加密模塊)
1、什么叫hash:hash是一種算法(3.x里代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),該算法接受傳入的內(nèi)容,經(jīng)過(guò)運(yùn)算得到一串hash值2、hash值的特點(diǎn)是:2.1 驗(yàn)證一致性:只要傳入的內(nèi)容一樣,得到的hash值必然一樣=====>要用明文傳輸密碼文件完整性 校驗(yàn)2.2 加密:不能由hash值返解成內(nèi)容=======》把密碼做成hash值,不應(yīng)該在網(wǎng)絡(luò)傳輸明文密 碼2.3 不可反推(如今已被反推):只要使用的hash算法不變,無(wú)論校驗(yàn)的內(nèi)容有多大,得到的hash值長(zhǎng)度是固定的
hash算法就像一座工廠,工廠接收你送來(lái)的原材料(可以用m.update()為工廠運(yùn)送原材料),經(jīng)過(guò)加工返回的產(chǎn)品就是hash值。
在我們輸入密碼后,就會(huì)現(xiàn)場(chǎng)經(jīng)行加密,返回非服務(wù)端一份加密值,服務(wù)器拿著我們加密的值經(jīng)行比較和記錄。
import hashlibm=hashlib.md5() # m=hashlib.sha256() m.update('hello'.encode('utf8')) # 在解釋器中使用的是utf8,所以需要解碼。 print(m.hexdigest()) # 5d41402abc4b2a76b9719d911017c592 hexdigest是十六進(jìn)制的編碼,而digest是十進(jìn)制 print(m.digest()) # b']A@*\xbcK*v\xb9q\x9d\x91\x10\x17\xc5\x92' m.update('alex'.encode('utf8')) print(m.hexdigest()) # 354ca34fd199b3cbcd45a7df7de2c5a6 m2 = hashlib.md5() m2.update('helloalex'.encode('utf8')) print(m.hexdigest()) # 354ca34fd199b3cbcd45a7df7de2c5a6 與之前一樣# 注意:把一段很長(zhǎng)的數(shù)據(jù)update多次,與一次update這段長(zhǎng)數(shù)據(jù),得到的結(jié)果一樣,但是update多次為校驗(yàn)大文件提供了可能以上加密算法雖然依然非常厲害,但時(shí)候存在缺陷,即:通過(guò)撞庫(kù)可以反解。所以,有必要對(duì)加密算法中添加自定義key再來(lái)
做加密。
import hashlib# ######## 256 ######## hash = hashlib.sha256('898oaFs09f'.encode('utf8')) # 在最開始加一個(gè)key,無(wú)序的 可以起到隱藏的作用 hash.update('alvin'.encode('utf8')) print (hash.hexdigest()) # e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7?模擬撞庫(kù)解碼:
import hashlib passwds=['alex3714','alex1313','alex94139413','alex123456','123456alex','a123lex',] def make_passwd_dic(passwds): # 用密碼生成的解碼對(duì)象生成一個(gè)字典dic={}for passwd in passwds:m=hashlib.md5()m.update(passwd.encode('utf-8'))dic[passwd]=m.hexdigest()return dicdef break_code(cryptograph,passwd_dic): # 判斷字典里的值是否和我們給出的一樣,從而打印出對(duì)應(yīng)的密碼for k,v in passwd_dic.items():if v == cryptograph:print('密碼是===>\033[46m%s\033[0m' %k) # 這里033[46m [0m是顏色 cryptograph='aee949757a2e698417463d47acac93df' break_code(cryptograph,make_passwd_dic(passwds))Python中還有一個(gè)hmac模塊,它的內(nèi)部對(duì)我們創(chuàng)建key和內(nèi)容進(jìn)一步的處理然后在加密
#要想保證hmac最終結(jié)果一致,必須保證: #1:hmac.new括號(hào)內(nèi)指定的初始key一樣 #2:無(wú)論update多少次,校驗(yàn)的內(nèi)容累加到一起是一樣的內(nèi)容import hmach1=hmac.new(b'egon') h1.update(b'hello') h1.update(b'world') print(h1.hexdigest())h2=hmac.new(b'egon') h2.update(b'helloworld') print(h2.hexdigest())h3=hmac.new(b'egonhelloworld') print(h3.hexdigest())''' f1bf38d054691688f89dcd34ac3c27f2 f1bf38d054691688f89dcd34ac3c27f2 bcca84edd9eeb86f30539922b28f3981 '''加鹽操作:
大家知道,根據(jù)MD5算法的不可推性,相同的密碼MD5值是一樣的,所以我們可以大量的撞庫(kù)來(lái)獲取值,那為了再給我們的MD5值
上一把鎖----->加鹽:“加鹽”就是對(duì)原密碼添加額外的字符串,然后再生成MD5值,這樣就沒有辦法進(jìn)行破解了(誰(shuí)也不知道你加的鹽是什么),除非拿到“加鹽”字符串,但碰撞方法也是需要一個(gè)一個(gè)重新計(jì)算MD5值后再進(jìn)行碰撞對(duì)比的,難度也是極其大的。那么看下面的代碼吧:
法一: import hashlib yan = '!任#意%字^符@' #定義加鹽字符串 pwd = input('>>>')md5_pwd = hashlib.md5() md5_pwd.update((pwd+yan).encode('UTF-8')) #加鹽 pwd = md5_pwd.hexdigest()#pwd = hashlib.new('md5',(pwd+yan).encode('UTF-8')).hexdigest() #也可以這樣簡(jiǎn)寫哦。。一句話搞定。 法二: import hashlib md5 = hashlib.md5('鹽'.encode('utf-8')) # 選擇加密方式 加鹽 md5.update('alex3714'.encode('utf-8')) # 將明文轉(zhuǎn)成字節(jié)然后進(jìn)行加密 print(md5.hexdigest()) # 生成密文 加鹽?
二、logging模塊
很多程序都有記錄日志的需求,并且日志中包含的信息即有正常的程序訪問日志,還可能有錯(cuò)誤、警告等信息輸出,python的logging模塊提供了標(biāo)準(zhǔn)的日志接口,你可以通過(guò)它存儲(chǔ)各種格式的日志,logging的日志可以分為?debug(),?info(),?warning(),?error()?and?critical()?5個(gè)級(jí)別,下面我們看一下怎么用。
import logginglogging.debug('調(diào)試debug') logging.info('消息info') logging.warning('警告warn') logging.error('錯(cuò)誤error') logging.critical('嚴(yán)重critical')''' WARNING:root:警告warn ERROR:root:錯(cuò)誤error CRITICAL:root:嚴(yán)重critical '''# 顯然前面的兩個(gè)沒有打印結(jié)果,因?yàn)榧?jí)別太低,且這五個(gè)級(jí)別遞增!用法:
import logginglogging.basicConfig(filename='example.log', level=logging.INFO) # 輸出到指點(diǎn)文件中,level = logging.INFO表示INFO即以上的等級(jí)才能打印 logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too')""" INFO:root:So should this WARNING:root:And this, too """似乎忽略了時(shí)間: logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
"""
09/08/2018 05:39:56 PM is when this event was logged.
"""
為logging模塊指定全局配置,針對(duì)所有l(wèi)ogger有效,控制打印到文件中
可在logging.basicConfig()函數(shù)中通過(guò)具體參數(shù)來(lái)更改logging模塊默認(rèn)行為,可用參數(shù)有filename:用指定的文件名創(chuàng)建FiledHandler(后邊會(huì)具體講解handler的概念),這樣日志會(huì)被存儲(chǔ)在指定的文件中。filemode:文件打開方式,在指定了filename時(shí)使用這個(gè)參數(shù),默認(rèn)值為“a”還可指定為“w”。format:指定handler使用的日志顯示格式。datefmt:指定日期時(shí)間格式。
level:設(shè)置rootlogger(后邊會(huì)講解具體概念)的日志級(jí)別
stream:用指定的stream創(chuàng)建StreamHandler。可以指定輸出到 sys.stderr,sys.stdout或者文件,默認(rèn)為sys.stderr。若同時(shí)列出了filename和stream兩個(gè)參數(shù),則stream參數(shù)會(huì)被忽略。#格式 %(name)s:Logger的名字,并非用戶名,詳細(xì)查看%(levelno)s:數(shù)字形式的日志級(jí)別%(levelname)s:文本形式的日志級(jí)別%(pathname)s:調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒有%(filename)s:調(diào)用日志輸出函數(shù)的模塊的文件名%(module)s:調(diào)用日志輸出函數(shù)的模塊名%(funcName)s:調(diào)用日志輸出函數(shù)的函數(shù)名%(lineno)d:調(diào)用日志輸出函數(shù)的語(yǔ)句所在的代碼行%(created)f:當(dāng)前時(shí)間,用UNIX標(biāo)準(zhǔn)的表示時(shí)間的浮 點(diǎn)數(shù)表示%(relativeCreated)d:輸出日志信息時(shí)的,自Logger創(chuàng)建以 來(lái)的毫秒數(shù)%(asctime)s:字符串形式的當(dāng)前時(shí)間。默認(rèn)格式是 “2003-07-08 16:49:45,896”。逗號(hào)后面的是毫秒%(thread)d:線程ID。可能沒有%(threadName)s:線程名。可能沒有%(process)d:進(jìn)程ID。可能沒有%(message)s:用戶輸出的消息
實(shí)例: #========使用 import logging logging.basicConfig(filename='access.log',format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',level=10) logging.debug('調(diào)試debug') logging.info('消息info') logging.warning('警告warn') logging.error('錯(cuò)誤error') logging.critical('嚴(yán)重critical')#========結(jié)果 access.log內(nèi)容: 2017-07-28 20:32:17 PM - root - DEBUG -test: 調(diào)試debug 2017-07-28 20:32:17 PM - root - INFO -test: 消息info 2017-07-28 20:32:17 PM - root - WARNING -test: 警告warn 2017-07-28 20:32:17 PM - root - ERROR -test: 錯(cuò)誤error 2017-07-28 20:32:17 PM - root - CRITICAL -test: 嚴(yán)重criticalpart2: 可以為logging模塊指定模塊級(jí)的配置,即所有l(wèi)ogger的配置
但是上面打印到屏幕和寫入文件只能選其一如果想同時(shí)把log打印在屏幕和文件日志里,就需要了解一點(diǎn)復(fù)雜的知識(shí) 了
Python 使用logging模塊記錄日志涉及四個(gè)主要類,使用官方文檔中的概括最為合適:
logger提供了應(yīng)用程序可以直接使用的接口;
handler將(logger創(chuàng)建的)日志記錄發(fā)送到合適的目的輸出;
filter提供了細(xì)度設(shè)備來(lái)決定輸出哪條日志記錄;
formatter決定日志記錄的最終輸出格式。
?
logger :產(chǎn)生日志的對(duì)象
每個(gè)程序在輸出信息之前都要獲得一個(gè)Logger。Logger通常對(duì)應(yīng)了程序的模塊名,比如聊天工具的圖形界面模塊可以這樣獲得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模塊可以這樣:
LOG=logging.getLogger(”chat.kernel”)
Logger.setLevel(lel):指定最低的日志級(jí)別,低于lel的級(jí)別將被忽略。debug是最低的內(nèi)置級(jí)別,critical為最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或刪除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或刪除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以設(shè)置的日志級(jí)別
?
?
handler
handler對(duì)象負(fù)責(zé)發(fā)送相關(guān)的信息到指定目的地。Python的日志系統(tǒng)有多種Handler可以使用。有些Handler可以把信息輸出到控制臺(tái),有些Logger可以把信息輸出到文件,還有些 Handler可以把信息發(fā)送到網(wǎng)絡(luò)上。如果覺得不夠用,還可以編寫自己的Handler。可以通過(guò)addHandler()方法添加多個(gè)多handler
Handler.setLevel(lel):? ?指定被處理的信息級(jí)別,低于lel級(jí)別的信息將被忽略
Handler.setFormatter(): 給這個(gè)handler選擇一個(gè)格式
Handler.addFilter(filt)、Handler.removeFilter(filt):? ?新增或刪除一個(gè)filter對(duì)象
每個(gè)Logger可以附加多個(gè)Handler。接下來(lái)我們就來(lái)介紹一些常用的Handler:
1) logging.StreamHandler
使用這個(gè)Handler可以向類似與sys.stdout或者sys.stderr的任何文件對(duì)象(file object)輸出信息。它的構(gòu)造函數(shù)是:
StreamHandler([strm])
其中strm參數(shù)是一個(gè)文件對(duì)象。默認(rèn)是sys.stderr
2) logging.FileHandler
和StreamHandler類似,用于向一個(gè)文件輸出日志信息。不過(guò)FileHandler會(huì)幫你打開這個(gè)文件。它的構(gòu)造函數(shù)是:
FileHandler(filename[,mode])
filename是文件名,必須指定一個(gè)文件名。
mode是文件的打開方式。參見Python內(nèi)置函數(shù)open()的用法。默認(rèn)是’a',即添加到文件末尾。
3) logging.handlers.RotatingFileHandler
這個(gè)Handler類似于上面的FileHandler,但是它可以管理文件大小。當(dāng)文件達(dá)到一定大小之后,它會(huì)自動(dòng)將當(dāng)前日志文件改名,然后創(chuàng)建 一個(gè)新的同名日志文件繼續(xù)輸出。比如日志文件是chat.log。當(dāng)chat.log達(dá)到指定的大小之后,RotatingFileHandler自動(dòng)把 文件改名為chat.log.1。不過(guò),如果chat.log.1已經(jīng)存在,會(huì)先把chat.log.1重命名為chat.log.2。。。最后重新創(chuàng)建 chat.log,繼續(xù)輸出日志信息。它的構(gòu)造函數(shù)是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode兩個(gè)參數(shù)和FileHandler一樣。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes為0,意味著日志文件可以無(wú)限大,這時(shí)上面描述的重命名過(guò)程就不會(huì)發(fā)生。
backupCount用于指定保留的備份文件的個(gè)數(shù)。比如,如果指定為2,當(dāng)上面描述的重命名過(guò)程發(fā)生時(shí),原有的chat.log.2并不會(huì)被更名,而是被刪除。
4) logging.handlers.TimedRotatingFileHandler
這個(gè)Handler和RotatingFileHandler類似,不過(guò),它沒有通過(guò)判斷文件大小來(lái)決定何時(shí)重新創(chuàng)建日志文件,而是間隔一定時(shí)間就 自動(dòng)創(chuàng)建新的日志文件。重命名的過(guò)程與RotatingFileHandler類似,不過(guò)新的文件不是附加數(shù)字,而是當(dāng)前時(shí)間。它的構(gòu)造函數(shù)是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename參數(shù)和backupCount參數(shù)和RotatingFileHandler具有相同的意義。
interval是時(shí)間間隔。
when參數(shù)是一個(gè)字符串。表示時(shí)間間隔的單位,不區(qū)分大小寫。它有以下取值:
S 秒
M 分
H 小時(shí)
D 天
W 每星期(interval==0時(shí)代表星期一)
midnight 每天凌晨
總結(jié)
#logger:產(chǎn)生日志的對(duì)象#Filter:過(guò)濾日志的對(duì)象#Handler:接收日志然后控制打印到不同的地方,FileHandler用來(lái)打印到文件中,StreamHandler用來(lái)打印到終端#Formatter對(duì)象:可以定制不同的日志格式對(duì)象,然后綁定給不同的Handler對(duì)象使用,以此來(lái)控制不同的Handler的日志格式1、logging模塊的Formatter、Hander、Logger、Filter對(duì)象實(shí)例
import logging#1、logger對(duì)象:負(fù)責(zé)產(chǎn)生日志,然后交給Filter過(guò)濾,然后交給不同的Handler輸出 logger=logging.getLogger(__file__)#2、Filter對(duì)象:不常用,略#3、Handler對(duì)象:接收l(shuí)ogger傳來(lái)的日志,然后控制輸出 h1=logging.FileHandler('t1.log') #打印到文件 h2=logging.FileHandler('t2.log') #打印到文件 h3=logging.StreamHandler() #打印到終端#4、Formatter對(duì)象:日志格式 formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',)formmater2=logging.Formatter('%(asctime)s : %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',)formmater3=logging.Formatter('%(name)s %(message)s',)#5、為Handler對(duì)象綁定格式 h1.setFormatter(formmater1) h2.setFormatter(formmater2) h3.setFormatter(formmater3)#6、將Handler添加給logger并設(shè)置日志級(jí)別 logger.addHandler(h1) logger.addHandler(h2) logger.addHandler(h3) logger.setLevel(10)#7、測(cè)試 logger.debug('debug') logger.info('info') logger.warning('warning') logger.error('error') logger.critical('critical')?2、Logger與Hander的級(jí)別
logger是第一級(jí)過(guò)濾,然后才能到handler,我們可以給logger和handler同時(shí)設(shè)置level,但是需要注意的是
略
3、Logger的繼承
import loggingformatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',)ch=logging.StreamHandler() ch.setFormatter(formatter)logger1=logging.getLogger('root') logger2=logging.getLogger('root.child1') logger3=logging.getLogger('root.child1.child2')logger1.addHandler(ch) logger2.addHandler(ch) logger3.addHandler(ch) logger1.setLevel(10) logger2.setLevel(10) logger3.setLevel(10)logger1.debug('log1 debug') logger2.debug('log2 debug') logger3.debug('log3 debug') ''' 2017-07-28 22:22:05 PM - root - DEBUG -test: log1 debug 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug '''?4、logging配置應(yīng)用
import os import logging.config# 定義三種日志輸出格式 開始 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \'[%(levelname)s][%(message)s]' #其中name為getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'# 定義日志輸出格式 結(jié)束 logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目錄 logfile_name = 'all2.log' # log文件名# 如果不存在定義的日志目錄就創(chuàng)建一個(gè) if not os.path.isdir(logfile_dir):os.mkdir(logfile_dir)# log文件的全路徑 logfile_path = os.path.join(logfile_dir, logfile_name)# log配置字典 LOGGING_DIC = {'version': 1,'disable_existing_loggers': False,'formatters': {'standard': {'format': standard_format},'simple': {'format': simple_format},},'filters': {},'handlers': {#打印到終端的日志'console': {'level': 'DEBUG','class': 'logging.StreamHandler', # 打印到屏幕'formatter': 'simple'},#打印到文件的日志,收集info及以上的日志'default': {'level': 'DEBUG','class': 'logging.handlers.RotatingFileHandler', # 保存到文件'formatter': 'standard','filename': logfile_path, # 日志文件'maxBytes': 1024*1024*5, # 日志大小 5M'backupCount': 5,'encoding': 'utf-8', # 日志文件的編碼,再也不用擔(dān)心中文log亂碼了 },},'loggers': {#logging.getLogger(__name__)拿到的logger配置'': {'handlers': ['default', 'console'], # 這里把上面定義的兩個(gè)handler都加上,即log數(shù)據(jù)既寫入文件又打印到屏幕'level': 'DEBUG','propagate': True, # 向上(更高level的logger)傳遞 },}, }def load_my_logging_cfg():logging.config.dictConfig(LOGGING_DIC) # 導(dǎo)入上面定義的logging配置logger = logging.getLogger(__name__) # 生成一個(gè)log實(shí)例logger.info('It works!') # 記錄該文件的運(yùn)行狀態(tài)if __name__ == '__main__':load_my_logging_cfg()?
?
三、collections模塊
collections是Python內(nèi)建的一個(gè)集合模塊,提供了許多有用的集合類。
1、namedtuple:是一個(gè)函數(shù),它用來(lái)創(chuàng)建一個(gè)自定義的tuple對(duì)象,并且規(guī)定了tuple元素的個(gè)數(shù),并可以用屬性而不是索引來(lái)引用tuple的某個(gè)元素。這樣一來(lái),我們用namedtuple可以很方便地定義一種數(shù)據(jù)類型,它具備tuple的不變性,又可以根據(jù)屬性來(lái)引用,使用十分方便。可以驗(yàn)證創(chuàng)建的Point對(duì)象是tuple的一種子類
>>> from collections import namedtuple >>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(1, 2) >>> p.x 1 >>> p.y 2 namedtuple >>> isinstance(p, Point) # p 是Point的對(duì)象 True >>> isinstance(p, tuple) #同時(shí)P也是tuple的對(duì)象 True 驗(yàn)證創(chuàng)建的是否是tuple類型2、deque:?使用list存儲(chǔ)數(shù)據(jù)時(shí),按索引訪問元素很快,但是插入和刪除元素就很慢了,因?yàn)閘ist是線性存儲(chǔ),數(shù)據(jù)量大的時(shí)候,插入和刪除效率很低。deque是為了高效實(shí)現(xiàn)插入和刪除操作的雙向列表,適合用于隊(duì)列和棧:
>>> from collections import deque >>> q = deque(['a', 'b', 'c']) >>> q.append('x') >>> q.appendleft('y') >>> q deque(['y', 'a', 'b', 'c', 'x'])#deque除了實(shí)現(xiàn)list的append()和pop()外,還支持appendleft()和popleft(),這樣就可以非常高效地往頭部添加或刪除元素。 depue3、defaultdict:?使用dict時(shí),如果引用的Key不存在,就會(huì)拋出KeyError。如果希望key不存在時(shí),返回一個(gè)默認(rèn)值,就可以用defaultdict
>>> from collections import defaultdict >>> dd = defaultdict(lambda: 'N/A') #括號(hào)內(nèi)可以設(shè)置可變數(shù)據(jù)類型 >>> dd['key1'] = 'abc' >>> dd['key1'] # key1存在 'abc' >>> dd['key2'] # key2不存在,返回默認(rèn)值 'N/A 1例題 li = [{'name':'alex','hobby':'抽煙'},{'name':'alex','hobby':'喝酒'},{'name':'alex','hobby':'燙頭'},{'name':'alex','hobby':'撩妹'},{'name':'wusir','hobby':'小寶劍'},{'name':'wusir','hobby':'游泳'},{'name':'wusir','hobby':'打牌'},{'name':'太白','hobby':'燙頭'},{'name':'太白','hobby':'洗腳'},{'name':'太白','hobby':'開車'}, ] d = defaultdict(list) #創(chuàng)建一個(gè)列表將一個(gè)字典裝起來(lái),當(dāng)然這里也可以創(chuàng)建其他類型,等價(jià)于{'x':[]} for i in li:d[i['name']].append(i['hobby']) print([dict(d)]) # 最后將其轉(zhuǎn)換成字典 2例題:將下面顏色相同的數(shù)字相加,最后得到顏色和對(duì)應(yīng)出現(xiàn)次數(shù)li = [('紅色',1),('黃色',1),('綠色',1),('藍(lán)色',1),('紅色',5),('綠色',1),('綠色',1),('綠色',1)] d = defaultdict(list) for i in li:d[i[0]].append(i[1]) dd = dict(d) for em in dd:dd[em] = sum(dd[em]) print(dd) #{'紅色': 6, '黃色': 1, '綠色': 4, '藍(lán)色': 1} defaultdict使用4、Counter:是一個(gè)簡(jiǎn)單的計(jì)數(shù)器,例如,統(tǒng)計(jì)字符出現(xiàn)的個(gè)數(shù)
>>> from collections import Counter >>> c = Counter() >>> for ch in 'programming': ... c[ch] = c[ch] + 1 ... >>> c #Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1}) Counter 1、 import collections login_user = [(r'http://www.baidu.com', 'usr1', 'pwd1'),(r'http://www.youdao.com', 'usr2', 'pwd2'),(r'http://mail.126.com', 'usr3', 'pwd3') ]page_info = collections.namedtuple('login_info', ['url', 'username', 'password']) for user in login_user:x = page_info(*user)print(x) 例題 # 上題運(yùn)行結(jié)果 login_info(url='http://www.baidu.com', username='usr1', password='pwd1') login_info(url='http://www.youdao.com', username='usr2', password='pwd2') login_info(url='http://mail.126.com', username='usr3', password='pwd3')#如果打印元組。可以直接使用print(tuple(x) View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/double-W/p/9610319.html
總結(jié)
以上是生活随笔為你收集整理的logging、hashlib、collections模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java编译器优化与运行期优化技术浅析
- 下一篇: yum更换国内源、yum下载rpm包、源