Python 學習拾遺

該博文主要適應於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+的區別,他們雖然都是讀寫模式,但使用效果是有差異的。

參考自:Python open()文件處理使用介紹

 

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進行排序。

詳見:python中對list去重的多種方法

 

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

相關文章
相關標籤/搜索