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 如何線程間通信
定義兩個線程肢执,Downloader
和 Coverter
前者是生產者,后者是消費者
可以通過一個全局變量來進行數(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)穿稳。