面向?qū)ο蟮某绦蛟O(shè)計(jì)具有封裝藐唠、繼承右钾、多態(tài)3個(gè)基本特征,可以大大增加程序可靠性复旬、代碼可重用行和程序可維護(hù)性垦缅,從而提高程序的開發(fā)效率。
類對(duì)象與實(shí)例對(duì)象
類對(duì)象
# 類對(duì)象
class 類名:
類體
class Person1:
pass
# 測(cè)試代碼
p1 = Person1()
print(Person1, type(Person1), id(Person1))
print(p1, type(p1), id(p1))
實(shí)例對(duì)象
# 實(shí)例對(duì)象
anObject = 類名(參數(shù)列表)
anObject.對(duì)象函數(shù) 或 anObject.對(duì)象屬性
Python創(chuàng)建實(shí)例對(duì)象的方法無需使用關(guān)鍵字new
驹碍,而是直接調(diào)用類對(duì)象并傳遞參數(shù)壁涎。因此,類對(duì)象是可調(diào)用對(duì)象志秃。
Python內(nèi)置函數(shù)中怔球,可調(diào)用內(nèi)置類對(duì)象bool / int / str / list / dict / set
# 實(shí)例對(duì)象的創(chuàng)建實(shí)例
c1 = complex(1, 2)
c1.conjugate()
c1.real
# output
(1-2j)
1.0
屬性
Python變量不需要聲明,可直接使用浮还。
實(shí)例對(duì)象屬性
通過“self.變量名”定義的屬性稱為實(shí)例對(duì)象屬性竟坛,也稱為實(shí)例對(duì)象變量。類的每個(gè)實(shí)例都包含了該類的實(shí)例對(duì)象變量的一個(gè)單獨(dú)副本,實(shí)例對(duì)象變量屬于特定的實(shí)例担汤。實(shí)例對(duì)象變量在類的內(nèi)部通過self訪問涎跨,在外部通過對(duì)象實(shí)例訪問。
# 實(shí)例對(duì)象屬性一般在__init__()方法中初始化
self.實(shí)例變量名 = 初始值
# 在其他實(shí)例函數(shù)中通過self訪問
self.實(shí)例變量名 = 值
# 創(chuàng)建對(duì)象實(shí)例后通過對(duì)象實(shí)例訪問
obj1 = 類名()
obj1.實(shí)例變量名 = 值
obj1.實(shí)例變量名
class Person2:
def __init__(self, name, age): # 初始化__init__()方法
self.name = name
self.age = age
def say_hi(self):
print('您好,我叫', self.name)
# 測(cè)試代碼
p1 = Person2('張三', 25)
p1.say_hi()
print(p1.age)
類對(duì)象屬性
class Person3:
count = 0
name = "Person"
類屬性如果通過obj.屬性名
來訪問崭歧,則屬于實(shí)例的實(shí)例屬性隅很。雖然類屬性可以使用對(duì)象實(shí)例來訪問,但容易造成困惑驾荣,訪問類屬性建議使用標(biāo)準(zhǔn)的訪問方式"類名.變量名"
私有屬性和共有屬性
Python類的成員沒有范文控制限制外构。
# 私有屬性:以兩下劃線開頭普泡,但不以兩下劃線結(jié)束
class A:
__name = 'class A'
def get_name():
print(A.__name)
A.get_name()
A.__name # 不可訪問私有類屬性
@property裝飾器
面向?qū)ο缶幊痰姆庋b性原則要求不直接訪問類中的數(shù)據(jù)成員播掷。在Python中可以定義私有屬性,然后定義相應(yīng)的訪問該私有屬性的函數(shù)撼班,并使用@property裝飾器來裝飾這些函數(shù)歧匈。程序可以把函數(shù)“當(dāng)作”屬性訪問,從而提供更加友好的訪問方式砰嘁。
class Person11:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
# 測(cè)試代碼
p = Person11('Estellasy')
print(p.name)
class Person12:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
self.__name = value
@name.deleter
def name(self):
del self.__name
#測(cè)試代碼
p = Person12('姚六')
p.name = '王依依'
print(p.name)
# property的調(diào)用格式如下
property(fget=None, fset=None, fdel=None, doc=None)
# 其中件炉,fget為get訪問器;fset為set訪問器矮湘;fdel為del訪問器
特殊屬性
以雙下劃線開始和結(jié)束的屬性
自定義屬性
@Override
方法
對(duì)象實(shí)例方法
在一般情況下斟冕,類方法的第一個(gè)參數(shù)一般為self,這種方法稱為對(duì)象實(shí)例方法缅阳。
def 方法名(self, [形參列表]):
函數(shù)體
對(duì)象.方法名([實(shí)參列表])
class Person4: #定義類Person4
def say_hi(self, name): #定義方法say_hi
self.name = name #把參數(shù)name賦值給self.name磕蛇,即成員變量name(域)
print('您好, 我叫', self.name)
p4 = Person4() #創(chuàng)建對(duì)象實(shí)例
p4.say_hi('Alice') #調(diào)用對(duì)象實(shí)例的方法
靜態(tài)方法
與類的對(duì)象實(shí)例無關(guān)的方法,稱之為靜態(tài)方法十办。
靜態(tài)方法不對(duì)特定實(shí)例進(jìn)行操作秀撇,在靜態(tài)方法中訪問對(duì)象實(shí)例會(huì)導(dǎo)致錯(cuò)誤。靜態(tài)方法通過裝飾器@staticmethod來定義向族,其聲明格式如下呵燕。
@staticmetho
def 靜態(tài)方法名([形參列表]):
函數(shù)體
一般通過類名來訪問,也可以通過對(duì)象實(shí)例來調(diào)用件相。
class TemperatureConverter:
@staticmethod
def c2f(t_c): #攝氏溫度到華氏溫度的轉(zhuǎn)換
t_c = float(t_c)
t_f = (t_c * 9/5) + 32
return t_f
@staticmethod
def f2c(t_f): #華氏溫度到攝氏溫度的轉(zhuǎn)換
t_f = float(t_f)
t_c = (t_f - 32) * 5 /9
return t_c
#測(cè)試代碼
print("1. 從攝氏溫度到華氏溫度.")
print("2. 從華氏溫度到攝氏溫度.")
choice = int(input("請(qǐng)選擇轉(zhuǎn)換方向:"))
if choice == 1:
t_c = float(input("請(qǐng)輸入攝氏溫度: "))
t_f = TemperatureConverter.c2f(t_c)
print("華氏溫度為: {0:.2f}".format(t_f))
elif choice == 2:
t_f = float(input("請(qǐng)輸入華氏溫度: "))
t_c = TemperatureConverter.f2c(t_f)
print("攝氏溫度為: {0:.2f}".format(t_c))
else:
print("無此選項(xiàng)再扭,只能選擇1或2!")
類方法
Python也允許聲明屬于類本身的方法夜矗,即類方法泛范。類方法不對(duì)特定實(shí)例進(jìn)行操作,在類方法中訪問對(duì)象實(shí)例屬性會(huì)導(dǎo)致錯(cuò)誤侯养。類方法通過裝飾器@classmethod來定義敦跌,第一個(gè)形式參數(shù)必須為類對(duì)象本身,通常為cls。
@classmethod
def 類方法名(cls, [形參列表]):
函數(shù)體
# 類方法一般通過類名來訪問柠傍,也可以通過對(duì)象實(shí)例來調(diào)用麸俘。
類名.類方法名([實(shí)參列表])
class Foo:
classname = "Foo"
def __init__(delf, name):
self.name = name
def f1(self):
print(self.name)
@staticmethod
def f2():
print("static")
@classmethod
def f3():
print(cls.classname)
#測(cè)試代碼
f = Foo("李")
f.f1()
Foo.f2()
Foo.f3()
在Python類體中可以定義特殊的方法,例如__new__()
方法和__init__()
方法惧笛。
__new__()
方法是一個(gè)類方法从媚,在創(chuàng)建對(duì)象時(shí)調(diào)用,返回當(dāng)前對(duì)象的一個(gè)實(shí)例患整,一般無須重載該方法拜效。
__init__()
方法即構(gòu)造函數(shù)(構(gòu)造方法),用于執(zhí)行類的實(shí)例的初始化工作各谚。在創(chuàng)建完對(duì)象后調(diào)用紧憾,初始化當(dāng)前對(duì)象的實(shí)例,無返回值昌渤。
class Person5: #定義類Person5
def __init__(self, name): #__init__方法
self.name = name #把參數(shù)name賦值給self.name赴穗,即成員變量name(域)
def say_hi(self): #定義類Person的方法say_hi
print('您好, 我叫', self.name)
p5 = Person5('Helen') #創(chuàng)建對(duì)象
p5.say_hi() #調(diào)用對(duì)象的方法
__del__
方法即析構(gòu)函數(shù)(析構(gòu)方法),用于實(shí)現(xiàn)銷毀類的實(shí)例所需的操作膀息,如釋放對(duì)象占用的非托管資源(例如:打開的文件般眉、網(wǎng)絡(luò)連接等)
默認(rèn)情況下,當(dāng)對(duì)象不再被使用時(shí)潜支,__del__
方法運(yùn)行甸赃,由于Python解釋器實(shí)現(xiàn)自動(dòng)垃圾回收,即無法保證這個(gè)方法究竟在什么時(shí)候運(yùn)行
通過del語句冗酿,可以強(qiáng)制銷毀一個(gè)對(duì)象實(shí)例埠对,從而保證調(diào)用對(duì)象實(shí)例的__del__
方法。
class Person3:
count = 0 #定義類域count已烤,表示計(jì)數(shù)
def __init__(self, name,age): #構(gòu)造函數(shù)
self.name = name #把參數(shù)name賦值給self.name鸠窗,即成員變量name(域)
self.age = age #把參數(shù)age賦值給self.age,即成員變量age(域)
Person3.count += 1 #創(chuàng)建一個(gè)實(shí)例時(shí)胯究,計(jì)數(shù)加1
def __del__(self): #析構(gòu)函數(shù)
Person3.count -= 1 #銷毀一個(gè)實(shí)例時(shí)稍计,計(jì)數(shù)減1
def say_hi(self): #定義類Person3的方法say_hi()
print('您好, 我叫', self.name)
def get_count(): #定義類Person3的方法get_count()
print('總計(jì)數(shù)為:', Person3.count)
print('總計(jì)數(shù)為:',Person3.count) #類名訪問
p31 = Person3('張三',25) #創(chuàng)建對(duì)象
p31.say_hi() #調(diào)用對(duì)象的方法
Person3.get_count() #通過類名訪問
p32 = Person3('李四',28) #創(chuàng)建對(duì)象
p32.say_hi() #調(diào)用對(duì)象的方法
Person3.get_count() #通過類名訪問
del p31 #刪除對(duì)象p31
Person3.get_count() #通過類名訪問
del p32 #刪除對(duì)象p32
Person3.get_count() #通過類名訪問
兩個(gè)下劃線開頭,但不以兩個(gè)下劃線結(jié)束的方法是私有的(private)裕循,其他為公共的(public).
以雙下劃線開始和結(jié)束的方法是Python的專有特殊方法臣嚣。不能直接訪問私有方法,但可以在其他方法中訪問
class Book: #定義類Book
def __init__(self, name, author, price):
self.name = name #把參數(shù)name賦值給self.name剥哑,即成員變量name(域)
self.author = author#把參數(shù)author賦值給self.author硅则,即成員變量author(域)
self.price = price #把參數(shù)price賦值給self.price,即成員變量price(域)
def __check_name(self): #定義私有方法株婴,判斷name是否為空
if self.name == '' : return False
else: return True
def get_name(self): #定義類Book的方法get_name
if self.__check_name():print(self.name,self.author) #調(diào)用私有方法
else:print('No value')
b = Book('Python程序設(shè)計(jì)教程','江紅',59.0) #創(chuàng)建對(duì)象
b.get_name() #調(diào)用對(duì)象的方法
b.__check_name() #直接調(diào)用私有方法怎虫,非法
方法重載
可以定義多個(gè)重名的方法暑认,只要保證方法簽名是唯一的
方法簽名包括三個(gè)部分:方法名、參數(shù)數(shù)量和參數(shù)類型
class Person21:
def say_hi(self, name = None):
self.name = name
if name == None:
print('您好')
else:
print('您好大审,我叫', self.name)
p21 = Person21()
p21.say_hi()
p21.say_hi('任思怡')
class Person22: #定義類Person22
def say_hi(self, name): #定義類方法say_hi蘸际,帶兩個(gè)參數(shù)
print('您好, 我叫', self.name)
def say_hi(self, name, age): #定義類方法say_hi,帶三個(gè)參數(shù)
print('hi, {0}, 年齡:{1}'.format(name,age))
p22 = Person22() #創(chuàng)建對(duì)象
p22.say_hi('Lisa', 22) #調(diào)用對(duì)象的方法
#p22.say_hi('Bob') #TypeError: say_hi() missing 1 required positional argument: 'age'
Python類體中定義多個(gè)重名的方法雖然不會(huì)報(bào)錯(cuò)徒扶,但只有最后一個(gè)方法有效粮彤,所以建議不要定義重名的方法。
繼承
派生類:python支持多重繼承姜骡,即一個(gè)派生可以繼承多個(gè)基類
聲明派生類時(shí)导坟,必須在其構(gòu)造函數(shù)中調(diào)用基類的構(gòu)造函數(shù)
class Person: #基類
def __init__(self, name, age): #構(gòu)造函數(shù)
self.name = name #姓名
self.age = age #年齡
def say_hi(self): #定義基類方法say_hi
print('您好, 我叫{0}, {1}歲'.format(self.name,self.age))
class Student(Person): #派生類
def __init__(self, name, age, stu_id): #構(gòu)造函數(shù)
Person.__init__(self, name, age) #調(diào)用基類構(gòu)造函數(shù)
self.stu_id = stu_id #學(xué)號(hào)
def say_hi(self): #定義派生類方法say_hi
Person.say_hi(self) #調(diào)用基類方法say_hi
print('我是學(xué)生, 我的學(xué)號(hào)為:', self.stu_id)
p1 = Person('張王一', 33) #創(chuàng)建對(duì)象
p1.say_hi()
s1 = Student('李姚二', 20, '2018101001') #創(chuàng)建對(duì)象
s1.say_hi()
查看繼承的層次關(guān)系
通過類的方法mro()或類的屬性__mro__
可以輸出其繼承的層次關(guān)系
class A: pass
class B(A): pass
class C(B): pass
class D(A): pass
class E(B, D): pass
D.mro()
E.__mro__
類成員的繼承和重寫
通過繼承,派生類繼承基類中除構(gòu)造方法之外的所有成員
如果在派生類中重新定義從基類繼承的方法圈澈,則派生類中定義的方法覆蓋從基類中繼承的方法
class Dimension: #定義類Dimensions
def __init__(self, x, y): #構(gòu)造函數(shù)
self.x = x #x坐標(biāo)
self.y = y #y坐標(biāo)
def area(self): #基類的方法area()
pass
class Circle(Dimension): #定義類Circle(圓)
def __init__(self, r): #構(gòu)造函數(shù)
Dimension.__init__(self, r, 0)
def area(self): #覆蓋基類的方法area()
return 3.14 * self.x * self.x #計(jì)算圓面積
class Rectangle(Dimension): #定義類Rectangle(矩形)
def __init__(self, w, h): #構(gòu)造函數(shù)
Dimension.__init__(self, w, h)
def area(self): #覆蓋基類的方法area()
return self.x * self.y #計(jì)算矩形面積
d1 = Circle(2.0) #創(chuàng)建對(duì)象:圓
d2 = Rectangle(2.0, 4.0) #創(chuàng)建對(duì)象:矩形
print(d1.area(), d2.area()) #計(jì)算并打印圓和矩形面積
Python面向?qū)ο蟪绦蛟O(shè)計(jì) 續(xù)
對(duì)象的特殊方法
- 包含許多以雙下劃線開始和結(jié)束的方法
- 創(chuàng)建對(duì)象實(shí)例時(shí)惫周,自動(dòng)調(diào)用
__init__
方法,a<b時(shí)士败,自動(dòng)調(diào)用對(duì)象a的__It__
方法
class Person:
def __init__(self, name, age): #特殊方法(構(gòu)造函數(shù))
self.name = name
self.age = age
def __str__(self): #特殊方法闯两,輸出成員變量
return '{0}, {1}'.format(self.name,self.age)
#測(cè)試代碼
p1 = Person('張三', 23)
print(p1)
運(yùn)算符重載與對(duì)象的特殊方法
Python的運(yùn)算符實(shí)際上是通過調(diào)用對(duì)象的特殊方法實(shí)現(xiàn)的
# 運(yùn)算符重載示例
class MyList: #定義類MyList
def __init__(self, *args): #構(gòu)造函數(shù)
self.__mylist = [] #初始化私有屬性褥伴,空列表
for arg in args:
self.__mylist.append(arg)
def __add__(self, n): #重載運(yùn)算符"+"谅将,每個(gè)元素增加n
for i in range(0, len(self.__mylist)):
self.__mylist[i] += n
def __sub__(self, n): #重載運(yùn)算符"-",每個(gè)元素減少n
for i in range(0, len(self.__mylist)):
self.__mylist[i] -= n
def __mul__(self, n): #重載運(yùn)算符"*"重慢,每個(gè)元素乘以n
for i in range(0, len(self.__mylist)):
self.__mylist[i] *= n
def __truediv__(self, n): #重載運(yùn)算符"/"饥臂,每個(gè)元素除以n
for i in range(0, len(self.__mylist)):
self.__mylist[i] /= n
def __len__(self): #對(duì)應(yīng)于內(nèi)置函數(shù)len(),返回列表長(zhǎng)度
return(len(self.__mylist))
def __repr__(self): #對(duì)應(yīng)于內(nèi)置函數(shù)str()似踱,顯示列表
str1 = ''
for i in range(0, len(self.__mylist)):
str1 += str(self.__mylist[i]) + ' '
return str1
#測(cè)試代碼
m = MyList(1, 2, 3, 4, 5) #創(chuàng)建對(duì)象
m + 2; print(repr(m)) #每個(gè)元素加2
m - 1; print(repr(m)) #每個(gè)元素減1
m * 4; print(repr(m)) #每個(gè)元素乘4
m / 2; print(repr(m)) #每個(gè)元素除2
print(len(m)) #列表長(zhǎng)度
@functools.total ordering裝飾器
支持大小比較的對(duì)象需要實(shí)現(xiàn)特殊方法:__eq__隅熙、__lt__、__le__核芽、__ge__囚戚、__gt__
使用functools模塊的total_ordering裝飾器裝飾類,則只需要實(shí)現(xiàn)__eq__
轧简,以及__lt__驰坊、__le__、__ge__哮独、__gt__
中的任意一個(gè)
total_ordering裝飾器實(shí)現(xiàn)其他比較運(yùn)算拳芙,以簡(jiǎn)化代碼量
import functools
@functools.total_ordering
class Student:
def __init__(self, firstname, secondname):
self.firstname = firstname
self.secondname = secondname
def __eq__(self, other): #判斷姓名是否一致
return ((self.lastname.lower(), self.firstname.lower()) == (other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other): #self姓名<other姓名
return ((self.lastname.lower(), self.firstname.lower()) < (other.lastname.lower(), other.firstname.lower()))
#測(cè)試代碼
if __name__ == '__main__':
s1 = Student('Mary','Clinton')
s2 = Student('Mary','Clinton')
s3 = Student('Charlie','Clinton')
print(s1==s2)
print(s1>s3)
__call__
方法和可調(diào)用對(duì)象(callabe)
Python類體中可以定義一個(gè)特殊的方法:__call__
方法
定義了__call__
方法的對(duì)象稱之為可調(diào)用對(duì)象
class GDistance:
def __init__(self, g):
self.g = g
def __call__(self, t):
return (self.g*t**2)/2
# 測(cè)試代碼
if __name__ = '__main__':
e_gdist = GDistance(9.8)
for t in range(11):
print(format(e_gdist(t), "0.2f"),end=' ')
對(duì)象的引用、淺拷貝和深拷貝
對(duì)象的引用:對(duì)象的賦值皮璧,
id
相同-
對(duì)象的淺拷貝:對(duì)象的賦值會(huì)引用同一個(gè)對(duì)象舟扎,即不拷貝對(duì)象
切片操作
對(duì)象實(shí)例化
copy函數(shù)
import copy acc1 = ['Charlie', ['credit', 0.0]] acc2 = acc1[:] # 使用切片方式拷貝對(duì)象 acc3 = list(ac1) # 使用對(duì)象實(shí)例化方法拷貝對(duì)象 acc4 = copy.copy(acc1) # 使用copy.copy函數(shù)拷貝對(duì)象 acc2[0] = 'Mary' acc2[1][1] = -99.9
-
對(duì)象的深拷貝:如果要遞歸復(fù)制對(duì)象中包含的子對(duì)象,可以使用copy模塊的deepcopy()函數(shù)
import copy acc1 = ['Charlie', ['credit', 0.0]] acc5 = copy.deepcopy(acc1) acc5[0] = 'Clinton' acc5[1][1] = -19.9
可迭代對(duì)象:迭代器和生成其
可循環(huán)迭代的對(duì)象稱之為可迭代對(duì)象悴务,迭代器和生成器函數(shù)是可迭代對(duì)象睹限。
相對(duì)于序列,可迭代序列僅在迭代時(shí)產(chǎn)生數(shù)據(jù),故可節(jié)省內(nèi)存空間羡疗。
Python語言提供了若干內(nèi)置可迭代對(duì)象:range\map\filter\enumerate\zip
標(biāo)準(zhǔn)庫itertools模塊中包含各種迭代器删窒。
可迭代對(duì)象:實(shí)現(xiàn)了__iter__()
的對(duì)象是可迭代對(duì)象
collections.abc
模塊中定義了抽象基類Iterable,使用內(nèi)置的isinstance顺囊,可以判斷一個(gè)對(duì)象是否為可迭代對(duì)象肌索。
import collections.abc
isinstance((1, 2, 3), collections.abc.Iterable)
isinstance('python33',collections.abc.Iterable)
isinstance(123,collections.abc.Iterable)
系列對(duì)象都是可迭代對(duì)象,生成器函數(shù)和生成器表達(dá)式也是可迭代對(duì)象特碳。
迭代器:實(shí)現(xiàn)了__next__()
的對(duì)象是迭代器
可以使用內(nèi)置函數(shù)next(), 調(diào)用迭代器的__next__
方法诚亚,一次返回下一個(gè)項(xiàng)目值
使用迭代器可以實(shí)現(xiàn)對(duì)象的迭代循環(huán),迭代器讓程序更加通用午乓、優(yōu)雅站宗、高校,更加python化益愈。
import collections.abc
i1 = (i**2 for i in range(10))
insinstance(i1, collections.abc.Iterator)
迭代器對(duì)象必須實(shí)現(xiàn)兩個(gè)方法:__iter__()
和__next()__
梢灭,二者合稱為迭代器協(xié)議。__iter__()
用于返回對(duì)象本身蒸其,以方便for語句進(jìn)行迭代敏释,__next()__
用于返回下一元素
自定義可迭代對(duì)象和迭代器
class Fib:
def __init__(self):
self.a, self.b = 0, 1
def __next__(self):
self.a, self.b = self.b, self.a + self.b
return self.a
def __iter__(self):
return self
# 測(cè)試代碼
fibs = Fib()
for f in fibs:
if f < 1000: print(f, end = ',')
else: break
生成器函數(shù)
生成器函數(shù)使用yield語句返回一個(gè)值,然后保存當(dāng)前函數(shù)整個(gè)執(zhí)行狀態(tài)摸袁,等待下一次調(diào)用钥顽。
生成器函數(shù)是一個(gè)迭代器,是可迭代對(duì)象靠汁,支持迭代
def gentripls(n):
for i in range(n):
yield i*3
f = gentripls(10)
反向迭代 reversed迭代器
使用內(nèi)置函數(shù)reversed()蜂大,可以實(shí)現(xiàn)一個(gè)系列的反向系列
如果一個(gè)可迭代對(duì)象實(shí)現(xiàn)了__reversed__()
方法,則可以使用reversed()函數(shù)獲得其反向迭代對(duì)象
生成器表達(dá)式
生成器表達(dá)式的語法和列表解析基本一樣蝶怔,只不過生成器表達(dá)式使用()代替[]
表達(dá)式expr使用每次迭代內(nèi)容iter_var奶浦,計(jì)算生成一個(gè)列表。如果指定了條件表達(dá)式cond_expr踢星,則只有滿足條件的iterable元素參與迭代
range可迭代對(duì)象
迭代時(shí)產(chǎn)生指定范圍的數(shù)字序列澳叉,可以節(jié)省內(nèi)存空間
map迭代器和itertool.starmap迭代器
map是可迭代對(duì)象,使用指定函數(shù)處理可迭代對(duì)象的每個(gè)元素(如果函數(shù)需要多個(gè)參數(shù)斩狱,則對(duì)應(yīng)各可迭代對(duì)象)耳高,返回結(jié)果可迭代對(duì)象
filter迭代器和itertools.filterfalse迭代器
filter是可迭代對(duì)象,使用指定函數(shù)處理可迭代對(duì)象的每個(gè)元素所踊,函數(shù)返回bool類型的值泌枪。若結(jié)果為True,則返回該元素秕岛。如果function為None碌燕,則返回元素為True的元素
>>> filter
<class 'filter'>
>>> list(filter(lambda x: x>0, (-1, 2, -3, 0, 5)))
[2, 5]
>>> list(filter(None, (1, 2, 3, 0, 5)))
[1, 2, 3, 5]
如果需要返回結(jié)果為False的元素误证,則需要使用itertools.filterfalse迭代器
filterfalse根據(jù)條件函數(shù)predicate處理可迭代對(duì)象的每個(gè)元素,若結(jié)果為True修壕,則丟棄愈捅;否則返回該元素
>>> import itertools
>>> list(itertools.filterfalse(lambda x: x%2, range(10)))
[0, 2, 4, 6, 8]
zip迭代器和itertools.zip_longest迭代器
zip是可迭代對(duì)象,拼接多個(gè)可迭代對(duì)象iter1慈鸠、iter2…的元素蓝谨,返回新的可迭代對(duì)象,其元素為各系列iter1青团、iter2…對(duì)象元素組成的元組譬巫。如果各系列iter1、iter2…的長(zhǎng)度不一致督笆,則截?cái)嘀磷钚∠盗虚L(zhǎng)度芦昔。可以節(jié)省內(nèi)存空間
>>> zip #<class 'zip'>
>>> zip((1,2,3),'abc', range(3)) # <zip object at 0x000001ED6C5A72C8>
>>> list(zip((1,2,3),'abc', range(3))) #[(1, 'a', 0), (2, 'b', 1), (3, 'c', 2)]
>>> list(zip('abc', range(10))) #[('a', 0), ('b', 1), ('c', 2)]
多個(gè)可迭代對(duì)象的元素個(gè)數(shù)不一致時(shí)娃肿,如果需要取最大的長(zhǎng)度咕缎,則需要使用itertools. zip_longest迭代器
>>> import itertools
>>> list(itertools.zip_longest('ABCD', 'xy', fillvalue='-'))
[('A', 'x'), ('B', 'y'), ('C', '-'), ('D', '-')]
enumerate迭代器
enumerate是可迭代對(duì)象,用于枚舉可迭代對(duì)象iterable中的元素料扰,返回元素為元組(計(jì)數(shù), 元素)的可迭代對(duì)象