該博文主要適應於python2.7,並無對py3進行測試。html
主要記錄學習python過程當中容易出現的一些小問題、小錯誤,相信能給你啓發。python
一、剔除一個字符串中的全部空格(假設該字符串是s)windows
"".join(s.split())後端
樣例輸入:python2.7
s = ' 123 4567 8 '函數
樣例輸出:學習
'12345678'測試
二、剔除文件名字符串中的非法字符(假設字符串是s)ui
有的時候從網上抓取下來的標題須要做爲文件名保存到本地(windows環境)編碼
可是windows下文件名中不能包含一些非法字符,例如‘/’、‘\’、‘?’ 神馬的
你能夠用下面這段代碼剔除標題中的非法字符
pattern = re.compile(r'[/\:*?"<>|]')
s = re.sub(pattern,'',s)
樣例輸入:
s = '<<?I am title?>>'
樣例輸出:
'I am title'
三、列表解析、base64解密、chr()、int()、join()函數使用
這是知道創宇的餘弦出的一個解密小遊戲,給你一個字符串,你須要解密出一個郵箱地址。
密碼字符串爲:
XDY1XDc2XDY5XDZjXDYzXDZmXDczXDQwXDY3XDZkXDYxXDY5XDZjXDJlXDYzXDZmXDZk
解密方式爲先用base64解密,再進行16進制轉換,最後按ASCII碼輸出每一個字符。
這個小遊戲頗有意思,能夠學習到一些python知識。
下面是解題步驟:
一、base64解密
s = 'XDY1XDc2XDY5XDZjXDYzXDZmXDczXDQwXDY3XDZkXDYxXDY5XDZjXDJlXDYzXDZmXDZk'
print base64.b64decode(s)
輸出:
\65\76\69\6c\63\6f\73\40\67\6d\61\69\6c\2e\63\6f\6d
這一看就是一種字符編碼,最早猜到是ASCII編碼。
爲了方便觀察,將其拆分:
print base64.b64decode(s).split('\\')
輸出:
['', '65', '76', '69', '6c', '63', '6f', '73', '40', '67', '6d', '61', '69', '6c', '2e', '63', '6f', '6d']
因爲每一個元素帶有字母,猜想是16進制數,轉換進制。
int(c,16) 能夠將字符串c當成16進制數,將其轉換成10進制數返回(注意返回的是一個整數)
chr(n) 能夠將一個整數n轉換成對應的ASCII字符。
因而有代碼:
for c in base64.b64decode(s).split('\\'):
if c: # 剔除空元素
print chr(int(c,16)),
輸出:
e v i l c o s @ g m a i l . c o m
以上代碼能夠用 列表解析 簡潔表示:
print [chr(int(c,16)) for c in base64.b64decode(s).split('\\') if c]
輸出:
['e', 'v', 'i', 'l', 'c', 'o', 's', '@', 'g', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm']
三、join()鏈接爲字符串
s.join(l) 表示將列表l中每一個字符鏈接成一個字符串,用字符串s做爲間隔
so,能夠將上述列表鏈接成字符串:
print ''.join([chr(int(c,16)) for c in base64.b64decode(s).split('\\') if c])
輸出:
evilcos@gmail.com
以上,就獲得餘弦大大的郵箱咯,是否是頗有意思?
4.理解python繼承的小例子
1 #coding=gbk
2 class A(object): 3 name = 'boss'
4 print name 5 def __init__(self,name=None): 6 print '2'
7 if name is not None: 8 self.name = name 9 print self.name 10
11
12 class B(A): 13 print '1'
14 name = 'Boss'
15
16 te = B()
運行結果:
boss 1
2 Boss
能夠看出類中變量和函數的繼承調用關係。
實例化B,先是運行從A繼承來的語句,運行結果:
boss
再運行B中的語句,運行結果:
1
最後調用從A繼承過來的構造函數__init__(),運行結果:
2 Boss
5.python列表解析中的雙重循環
如何將B列表中的每個元素與A列表中的元素相加,生成一個新列表?
請看如下代碼:
1 A = [1,2,3] 2 B = [4,5,6] 3 print [x+y for x in A for y in B]
以上列表解析的寫法至關於一個雙重循環,先遍歷B中每個元素,再遍歷A中每個元素,每輪循環進行元素相加操做,最後獲得一個新列表。
6.max()的比較函數
max()函數原型:
max(arg1, arg2, *args[, key])
例子:
1 #coding=gbk
2 A = [1,3,5,2,4] 3
4 print max(A) # 輸出A中最大的元素
5 print max(A,key=lambda x:x>2) # 輸出A中第一個大於2的元素
6
7 print max('af', 'be','cd') # 輸出最大的字符串,比較規則爲默認的字符串比較規則
8 print max('af', 'be','cd', key=lambda x: x[1]) # 輸出第二個字符最大的字符串
輸出:
5
3 cd af
key參數值爲一個函數入口指針,你能夠將本身定義的函數做爲參數傳進來,max函數將根據你定義的函數來進行比較,你能夠本身制訂比較規則。
lambda爲python中一種定義函數(匿名函數)的方法,你也能夠用def定義。
7.reverse()函數有返回值嗎?
請看如下代碼,猜猜它會輸出什麼呢?
1 A = [1,2,3] 2 print A.reverse()
是否是第一眼覺得會輸出 [3,2,1] ?哈哈,錯了。真正的輸出是:
None
看一下reverse()的語法:
list.reverse()
參數:NA
返回值:該方法沒有返回值,可是會對列表的元素進行反向排序。
8.提取url中的host(域名)
使用urllib庫提供的函數,用法以下:
1 import urllib 2
3 protocol, rest = urllib.splittype('https://www.cnblogs.com:80/yym2013') 4 # protocol : https
5 # rest : //www.cnblogs.com:80/yym2013
6
7 host, rest = urllib.splithost(rest) 8 # host : www.cnblogs.com:80
9 # rest : /yym2013
10
11 host, port = urllib.splitport(host) 12 # host : www.cnblogs.com
13 # port : 80
參考自: python 獲取url的host
9.if-else 單行書寫方法
if a>b: t = a else: t = b
轉換成if-else單行形式:
t = a if a>b else b
10.open的文件打開模式
r或rt 默認模式,文本模式讀 rb 二進制文件 w或wt 文本模式寫,打開前文件存儲被清空 wb 二進制寫,文件存儲一樣被清空 a 追加模式,只能寫在文件末尾 a+ 可讀寫模式,寫只能寫在文件末尾 w+ 可讀寫,與a+的區別是要清空文件內容 r+ 可讀寫,與a+的區別是能夠寫到文件任何位置
特別注意:a+、w+、r+的區別,他們雖然都是讀寫模式,但使用效果是有差異的。
11.關於文件讀寫錯誤 IOError: [Errno 0] Error
該錯誤一般在windows環境下,使用a+讀寫模式打開文件,並對其先進行read()讀操做,而後進行write()寫入操做後出現的。緣由是沒有進行flush或者seek等操做,python不知道文件位置在哪了。
參考自:python IOError: [Errno 0] Error - freeDynasty
十二、使用python發送郵件
參考自:使用python發送郵件
1三、python的編號迭代
有時候想用下標記錄當前遍歷的位置,同時又想有當前元素,自建一個變量變量做爲下標又太low,優雅一些的作法是用內建函數enumerate()進行迭代。
這樣既會有下標,又會有當前迭代元素。
for index,s in enumerate(str): print '%d==>%s'%(index,s)
1四、list元素去重
我比較喜歡用set集合進行去重,另外若是要保留list的順序的話,須要使用sort進行排序。
1五、如何用盡可能簡潔的代碼輸出一個列表(list)的前五個元素
最直觀的寫法,定義一個下標變量index來控制輸出:
1 li = [1,2,3,4,5,6,7,8,9,10] 2 index = 0 3 for x in li: 4 if index>=5: 5 break
6 print x 7 index+=1
觀察代碼,發現下標index能夠用enumerate函數直接分離出來:
1 li = [1,2,3,4,5,6,7,8,9,10] 2 for index,x in enumerate(li): 3 if index>=5: 4 break
5 print x
還有更簡單的寫法,使用列表的切片操做來簡化代碼:
1 li = [1,2,3,4,5,6,7,8,9,10] 2 for x in li[:5]: 3 print x
1六、readlines()會讀入換行符!
在一次用smtp服務發送郵件給本身的時候,我用readlines()讀取本地文件。
將帶有email的username和password的那兩行行直接賦值給用戶名和密碼變量。
結果致使收到的郵件開頭帶有亂碼,檢查了各個地方都沒有發現bug在哪裏。
最後找到緣由是輸入的用戶名和密碼最後分別帶有一個換行符,而郵件將多餘的內容做爲亂碼來處理了。
解決方法是readlines()讀取每一行內容後,賦值的時候須要先strip()去除字符串先後端多餘的空白符。
Freecode# : www.cnblogs.com/yym2013