《Python高級編程技巧》學習筆記

2-1列表、字典、集合篩選數(shù)據

  • filter
from random import randint
data = [randint(-10,10) for _ in xrange(10)]
filter(lambda x : x>=0,data)  
  • 推導式

在 Ipython 中使用 timeit可以進行計時
timeit filter(lambda x : x =='a',data)

2-2命名元祖

from collections import namedtuple 
p = namedtuple('Point',['x','y'])
p.x,p.y=1,2
print p.x+p.y

2-3 統(tǒng)計元素出現(xiàn)頻率

from collections import Counter
from random import randint

data = [randint(0,20) for _ in xrange(20)]
c = Counter(data)
print c.most_common(1)

2-4根據字典的值排序

  • 使用 zip
  • 使用 sort
from random import randint                                                               
d = {x:randint(0,100) for x in 'xyzabc'}  
print sorted(zip(d.values(),d.keys()))
print sorted(d.items(),key=lambda x:x[1])

2-5獲取字典公共鍵

1.使用 viewkeys 方法獲得集合再取交集
2.使用 map函數(shù)獲取所有字典的 key 的集合
3.使用 reduce函數(shù)依次取交集

from random import randint,sample
s1={x:randint(1,4) for x in sample('abcdefg',randint(3,6))} 
s2={x:randint(1,4) for x in sample('abcdefg',randint(3,6))} 
s3={x:randint(1,4) for x in sample('abcdefg',randint(3,6))} 
reduce(lambda a,b:a&b,map(dict.viewkeys,[s1,s2,s3])) 

2-6有序字典

from time import time
from random import randint
from collections import OrderedDict
d = OrderedDict()
players = list('ABCDEFGH')
start = time()

for i in xrange(8):
    raw_input()
    p = players.pop(randint(0,7-i))
    end = time()
    print i+1,p,end -start,
    d[p]=(i+1,end-start)
    
print

for k in d:
    print k,d[k]                            

2-7利用隊列實現(xiàn)歷史記錄

from collections import deque 
q = deque([],5) 

3-1可迭代對象和迭代器對象

  • 可迭代對象能夠通過iter()函數(shù)得到一個迭代器對象
  • 實現(xiàn)了__iter____getitem__方法的對象是可迭代對象

3-2實現(xiàn)可迭代對象和迭代器

  • 可迭代對象沾瓦,要實現(xiàn)__iter__方法系瓢,該方法要返回一個迭代器浮庐。
  • 迭代器要實現(xiàn)一個next()函數(shù)弹惦,該函數(shù)返回一個結果,同時需要在結束時拋出StopIteraion異常
  • 可以直接把__iter__實現(xiàn)為一個生成器

3-4實現(xiàn)反向迭代

  • 實現(xiàn)__reversed__函數(shù)
class FloatRange:
    def __init__(self, start, end, step=0.1):
        self.start = start
        self.end = end
        self.step = step

    def __iter__(self):
        t = self.start
        while t <= self.end:
            yield t
            t += self.step

    def __reversed__(self):
        t = self.end
        while t >= self.start:
            yield t
            t -= self.step
for x in reversed(FloatRange(1.0, 4.0, 0.5)):
    print x

3-5對可迭代對象使用切片

from itertools import islice 

Docstring:
islice(iterable, [start,] stop [, step]) --> islice object

Return an iterator whose next() method returns selected values from an
iterable. If start is specified, will skip all preceding elements;
otherwise, start defaults to zero. Step defaults to one. If
specified as another value, step determines how many values are
skipped between successive calls. Works like a slice() on a list
but returns an iterator.
Type: type

這個函數(shù)使用后喉恋,會消耗掉已經生成的元素

3-6同時迭代多個可迭代對象

  • 并行:zip()
  • 串行:from itertools import chain

4-1拆分多種分隔符的字符串

  • 反復使用split函數(shù)
def mysplit(s,ds):                                                               
      res = [s]                                                                    
      for d in ds:                                                                 
          t = []                                                                   
          map(lambda x : t.extend(x.split(d)),res)                                 
          res = t                                                                  
      return res 
  • 使用re.split()函數(shù)

4-3 如何調整字符串中文本的格式

re.sub('(\d{4})-(\d{2})-(\d{2})',r'\2/\3/\1',log)  

4-4拼接多個短字符串

  • 累加
  • join()函數(shù)沃饶,接受一個可迭代的字符串對象

4-5 如何對字符串進行左, 右, 居中對齊

  • str.ljust(),str.rjust(),str.center()
s.ljust(20,'*')                                                                 
Out[13]: 'abc*****************'
  • format()配置參數(shù)>20 <20 ^20
format(s,'<20')                                                                 
Out[19]: 'abc                 ' 

4-6 如何去掉字符串中不需要的字符

  • strip(),lstrip(),rstrip()去除兩端字符
  • re.sub或者replace
  • translate

S.translate(table [,deletechars]) -> string

Return a copy of the string S, where all characters occurring
in the optional argument deletechars are removed, and the
remaining characters have been mapped through the given
translation table, which must be a string of length 256 or None.
If the table argument is None, no translation is applied and
the operation simply removes the characters in deletechars.
Type: builtin_function_or_method

5 文件操作

6 解析 cvs,xml轻黑,excel糊肤,json

6.1解析 cvs

import cvs
rf = open('file.cvs','rb')
reader = cvs.reader(rf)#生成器
reader.next()

wf = open('file.cvs','r')
writer = cvs.writer(wf)#生成器
writer.next()


6.2解析 xml

7 類與對象

7-1 如何派生內置不可變類型并修改實例化行為

派生一個元組類型,只保留整型

class IntTuple(tuple):
    def __new__(cls,iterable):
        g = (x for x in iterable if isinstance(x,int))
        return super(IntTuple,cls).__new__(cls,g)
        
    def __init__(self,iterable):
        super(IntTuple,self).__init__(iterable)
        
t = IntTuple([1,-1,'abc',['x','y'],3])
print t

7-2 利用__slot__來節(jié)省對象的內存開銷

當我們不使用__slot__時苔悦,類對象使用一個 dict 來對對象的屬性進行動態(tài)綁定轩褐。對象的屬性就是該字典中的一個元素,可以動態(tài)添加或解除玖详。

p = Player()
p.__dict__['x']=1
>> p.x = 1

該機制需要維護一個字典把介,占據大量空間。

使用預定義的 __slot__ = ['x','y']蟋座,可以預定義對象的屬性拗踢,不允許動態(tài)添加。

7-3 如何讓對象支持上下文管理

讓對象支持 with 語句向臀,需要定義 __enter____exit__函數(shù)

def __enter__(self):
    self.tn = Telnet()
    return self
def __exit__(self):
    self.tn.close()

當發(fā)生異常時巢墅,能正確調用__exit__,如果該函數(shù)返回一個 True券膀,則可以壓制 with 語句中的異常君纫。

7-4 如何創(chuàng)建可管理的對象屬性

利用 getter 和 setter 來管理對象屬性,但是這樣做調用起來比較麻煩芹彬⌒钏瑁可以使用@property裝飾器來簡化

class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

當然也可以利用property() 函數(shù)

R = property(getter,setter)
C.R = 1 #調用 getter
print C.R #調用 setter

7-5 如何讓類支持比較操作

  • 實現(xiàn) __lt__,__ie__,__gt__,__ge__,__eq__,__ne__
  • 裝飾器 @total_ordering可以通過邏輯運算自動進行推測,我們可以只定義小于和等于兩種比較運算符
  • 對于兩個不同的類的對象舒帮,如果其中一個類實現(xiàn)了比較会喝,那么當這個類作為比較運算符的左值時才可以正確執(zhí)行,否則不等式兩邊的類都要實現(xiàn)全部相關比較操作符
  • 為了應對上述問題玩郊,我們可以定義一個抽象的公共基類
from abc import abstractmethod
class shape(object):
    @abstractmethod
    def area(self):
        pass
    def __lt__(self,obj):
        return self.area()<obj.area()

class rect(shape):
    def area(self):
        return self.x * self.y
class tri(shape):
    def area(self):
        return 0.5*self.x * self.h

7-6 如何使用描述符對實例屬性做類型檢查

8 多線程

8-1 如何使用多線程


from threading import Thread

class myThread(Thread):
    def __init__(self,sid):
        Thread.__init__(self)
        self.sid = sid
    def run(self):
        handle(self.sid)
 
threads = []       
for i in range(1,11):
    t = myThread(i)
    threads.append(t)
    t.start()
for t in threads:
    t.join() #必須在不同的循環(huán)中調用 join 否則會依次阻塞變成線性執(zhí)行

python 中的線程只適合處理 IO 密集型操作而不是 CPU 密集型操作

8-2 如何線程間通信

定義兩個線程肢执,DownloaderCoverter前者是生產者,后者是消費者
可以通過一個全局變量來進行數(shù)據通信译红,但是再操作數(shù)據前要調用 lock 函數(shù)加鎖预茄。或者可以使用線程安全的數(shù)據結構侦厚,例如from Queue import Queue 耻陕。
通常情況下昵慌,使用全局變量是不優(yōu)雅的,可以通過構造器將隊列傳入淮蜈,并使用 self.queue來維護。

8-3 如何在線程間進行事件通知

每下載100個 xml 文件已卷,通知壓縮線程來壓縮梧田,壓縮線程執(zhí)行完畢后,再通知下載函數(shù)繼續(xù)下載

ipython 中輸入侧蘸!開頭的命令裁眯,可以執(zhí)行 shell 命令

from threading import Event,Thread    
class CovertThread(Thread):
    def __init__(self,cEvent,tEvent):
        Thread.__init__(self)
        self.cEvent = cEvent
        self.tEvent = cEvent
        self.count = 0
    def csv2xml(self,data,wf):
        pass
    def run():
        count = 1
        while True:
            self.csv2xml(data,wf):
                count +=1
            id count == 100:
                self.cEvent.set()
                self.tEvent.wait()
                self.cEvent.clear()
                count = 0
class TarThread(Thread):
    def __init__(self,cEvent,tEvent):
        Thread.__init__(self)
        self.cEvent = cEvent
        self.tEvent = cEvent
        self.count = 0
        self.setDaemon(True) #設置為守護進程
    def tarXml(self):
        self.count += 1
        tfname = '%d.tar'%self.count
        tf = tarfile.open(tfname,'w:gz')
        for fname in os.listdir('.'):
            if fname.endwith('xml'):
                tf.add(frame)
                os,remove(fname)
        tf.close()
        
        if not tf.members:
            os.remove(tfname)
    def run(self):
        while True:
            self.cEvent.wait() #等待事件
            self.tarXml() #打包
            self.cEvent.clear() #清空當前狀態(tài)
            self.tEvent.set() #發(fā)送消息

共同維護兩個 Event,并通過 set 和 wait 來發(fā)送消息讳癌,通過clear 清除當前狀態(tài)穿稳。

8-4 如何使用線程本地數(shù)據

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晌坤,隨后出現(xiàn)的幾起案子逢艘,更是在濱河造成了極大的恐慌,老刑警劉巖骤菠,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件它改,死亡現(xiàn)場離奇詭異,居然都是意外死亡商乎,警方通過查閱死者的電腦和手機央拖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鹉戚,“玉大人鲜戒,你說我怎么就攤上這事∧ǖ剩” “怎么了遏餐?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長却桶。 經常有香客問我境输,道長,這世上最難降的妖魔是什么颖系? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任嗅剖,我火速辦了婚禮,結果婚禮上嘁扼,老公的妹妹穿的比我還像新娘信粮。我一直安慰自己,他們只是感情好趁啸,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布强缘。 她就那樣靜靜地躺著督惰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旅掂。 梳的紋絲不亂的頭發(fā)上赏胚,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音商虐,去河邊找鬼觉阅。 笑死,一個胖子當著我的面吹牛秘车,可吹牛的內容都是我干的典勇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叮趴,長吁一口氣:“原來是場噩夢啊……” “哼割笙!你這毒婦竟也來了?” 一聲冷哼從身側響起眯亦,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤伤溉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后妻率,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谈火,經...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年舌涨,在試婚紗的時候發(fā)現(xiàn)自己被綠了糯耍。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡囊嘉,死狀恐怖温技,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情扭粱,我是刑警寧澤舵鳞,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站琢蛤,受9級特大地震影響蜓堕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜博其,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一套才、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慕淡,春花似錦背伴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽息尺。三九已至,卻和暖如春疾掰,著一層夾襖步出監(jiān)牢的瞬間搂誉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工静檬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勒葱,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓巴柿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親死遭。 傳聞我的和親對象是個殘疾皇子广恢,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內容