1.36 函數iter()
在Python程式中,使用函數iter()的文法格式如下所示。
iter(object[, sentinel])
- object:支援疊代的集合對象;
- sentinel:如果傳遞了第二個參數,則參數 object 必須是一個可調用的對象(如,函數),此時,iter 建立了一個疊代器對象,每次調用這個疊代器對象的__next__()方法時,都會調用 object。
函數iter()的功能是傳回一個疊代器對象。根據有無第二個參數,對第一個參數的解釋相差很大。沒有第二個參數sentinel,object必須是一個支援疊代協定(__iter__()方法)的容器對象,或者它必須支援序列協定(從 0開始的整數參數的__getitem__() 方法)。如果它不支援這些協定任何一個,将引發TypeError。如果給出第二個參數sentinel,那麼object必須是一個可調用的對象。這種情況下建立的疊代器将在每次調用時不帶參數調用object的__next__()方法;如果傳回的值等于sentinel,将引發StopIteration,否則傳回這個值。
例如在下面的執行個體檔案ite.py中,示範了用函數iter()疊代處理指定對象的過程。
a = iter({'A': 1, 'B': 2}) # 字典集合
print(a)
print(next(a))
print(next(a))
a = iter('abcd') # 字元串序列
print(a)
print(next(a))
print(next(a))
print(next(a))
print(next(a))
在使用函數iter()的過程中,當提供第二個參數sentinel時,第一個參數必須是一個可被調用對象。建立的疊代對象,在調用__next__方法的時候會調用這個可被調用對象,當傳回值和sentinel值相等時,将抛出StopIteration異常,并終止疊代。例如下面的示範過程。
# 定義類
>>> class IterTest:
def __init__(self):
self.start = 0
self.end = 10
def get_next_value(self):
current = self.start
if current < self.end:
self.start += 1
else:
raise StopIteration
return current
>>> iterTest = IterTest() #執行個體化類
>>> a = iter(iterTest.get_next_value,4) # iterTest.get_next_value為可調用對象,sentinel值為4
>>> a
<callable_iterator object at 0x03078D30>
>>> next(a)
0
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
>>> next(a) #疊代到4終止
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
next(a)
StopIteration
1.37 函數len()
在Python程式中,使用函數len()的文法格式如下所示。
len( s )
函數len()的功能是傳回參數s的長度或項目個數,參數s表示對象,可以是可以是序列(如字元串,位元組,元組,清單或者範圍)或者集合(如字典,集合或者固定集合)等。例如在下面的執行個體檔案len.py中,示範了使用函數len()傳回指定對象長度的過程。
str = "toppr"
print(len(str) ) # 字元串長度
l = [1,2,3,4,5]
print(len(l)) # 清單元素個數
print(len('abcd')) # 字元串
print(len(bytes('abcd','utf-8')))# 位元組數組
print(len((1,2,3,4))) # 元組
print(len([1,2,3,4])) # 清單
print(len(range(1,5))) # range對象
print(len({'a':1,'b':2,'c':3,'d':4}))# 字典
print(len({'a','b','c','d'}))# 集合
print(len(frozenset('abcd')))#不可變集合
執行後會輸出:
5
5
4
4
4
4
4
4
4
4
如果函數len()的參數為其它類型,則其必須實作__len__方法,并傳回整數,否則報錯。例如下面的示範過程。
>>> class A:
def __init__(self,name):
self.name = name
def __len__(self):
return len(self.name)
>>> a = A('')
>>> len(a)
0
>>> a = A('Aim')
>>> len(a)
3
>>> class B:
pass
>>> b = B()
>>> len(b)
Traceback (most recent call last):
File "<pyshell#65>", line 1, in <module>
len(b)
TypeError: object of type 'B' has no len()
>>> class C:
def __len__(self):
return 'len'
>>> c = C()
>>> len(c)
Traceback (most recent call last):
File "<pyshell#71>", line 1, in <module>
len(c)
TypeError: 'str' object cannot be interpreted as an integer
1.38 函數list()
在Python程式中,使用函數list()的文法格式如下所示。
list( seq )
函數list()實際是上清單類型的構造函數的功能是将元組seq轉換為清單。元組與清單是非常類似的,差別在于元組的元素值不能修改,元組是放在括号中,清單是放于方括号中。
例如在下面的執行個體檔案list.py中,示範了用函數list()将元組轉換為清單的過程。
aTuple = (123, 'Google', 'Toppr', 'Taobao')
list1 = list(aTuple)
print ("清單元素 : ", list1)
str="Hello World"
list2=list(str)
print ("清單元素 : ", list2)
#可以不傳入任何參數,結果傳回一個空清單。
a = list()
print(a)
#可以傳入一個可疊代對象,如字元串,位元組數組、元組、清單、range對象,結果将傳回可疊代對象中元素組成的清單。
print(list('abcd'))# 字元串
print(list(bytes('abcd','utf-8')))# 位元組數組
print(list(('a','b','c','d')))# 元組
print(list(['a','b','c','d']))# 清單
print(list(range(1,5)))# range對象
執行後會輸出:
清單元素 : [123, 'Google', 'Toppr', 'Taobao']
清單元素 : ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
[]
['a', 'b', 'c', 'd']
[97, 98, 99, 100]
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd']
[1, 2, 3, 4]
1.39 函數locals()
在Python程式中,使用函數locals()的文法格式如下所示。
locals()
函數locals()的功能是以字典類型傳回目前位置的全部局部變量。對于函數、方法、lambda 、類,以及實作了 __call__ 方法的類執行個體, 都會傳回True。當locals()在函數代碼塊中調用時會傳回自由變量,但是在類代碼塊中不會。
例如在下面的執行個體檔案local.py中,示範了用函數locals()傳回目前作用域内的局部變量和其值組成的字典的過程, 其功能與globals()類似(傳回全局變量)。
print(locals())
a = 1
print(locals())# 多了一個key為a值為1的項
執行後會輸出:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002AB4FF2B588>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'local.py', '__cached__': None}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002AB4FF2B588>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'local.py', '__cached__': None, 'a': 1}
在下面的執行個體檔案local1.py中,示範了将函數locals()用于函數内的過程。
def f():
print('before define a ')
print(locals()) # 作用域内無變量
a = 1
print('after define a')
print(locals()) # 作用域内有一個a變量,值為1
print(f)
f()
執行後會輸出:
<function f at 0x000001C40C613EA0>
before define a
{}
after define a
{'a': 1}
在下面的執行個體檔案local2.py中,示範了不能修改函數locals()傳回的字典集合的過程。
def f():
print('before define a ')
print(locals()) # 作用域内無變量
a = 1
print('after define a')
print(locals()) # 作用域内有一個a變量,值為1
b = locals()
print('b["a"]: ', b['a'])
b['a'] = 2 # 修改b['a']值
print('change locals value')
print('b["a"]: ', b['a'])
print('a is ', a) # a的值未變
f()
執行後會輸出:
before define a
{}
after define a
{'a': 1}
b["a"]: 1
change locals value
b["a"]: 2
a is 1
1.40 函數map()
在Python程式中,使用函數map()的文法格式如下所示。
map(function, iterable, ...)
- function:函數,有兩個參數;
- iterable:一個或多個序列。
函數map()的功能是根據提供的函數對指定序列做映射。第一個參數 function 以參數序列中的每一個元素調用 function 函數,傳回包含每次 function 函數傳回值的新清單。函數map()最終會傳回一個疊代器,對iterable的每個項應用function,并yield結果。如果傳遞多個iterable參數,function必須接受這麼多參數,并應用到從iterables并行提取的項中。如果有多個iterable,疊代器則在最短的iterable耗盡時停止。
在下面的執行個體檔案map.py中,示範了使用函數map()實作資料映射的過程。
def square(x): # 計算平方數
return x ** 2
print(map(square, [1, 2, 3, 4, 5])) # 計算清單各個元素的平方
①print(list(map(square, [1, 2, 3, 4, 5])))
print(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # 使用 lambda 匿名函數
②print(list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])))
#提供了兩個清單,對相同位置的清單資料進行相加
print(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
③print(list(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])))
因為函數map()在Python 2版本中傳回清單,在Python 3版本中傳回疊代器。是以當在Python 3中執行上述代碼時,在①②③中使用list()函數處理為清單格式。執行後會輸出:
<map object at 0x000002C0E1EFFA90>
[1, 4, 9, 16, 25]
<map object at 0x000002C0E1E2A6D8>
[1, 4, 9, 16, 25]
<map object at 0x000002C0E20A5FD0>
[3, 7, 11, 15, 19]
如果函數map()有多個參數, 但每個參數的序列元素數量不一樣, 則會根據最少元素的序列進行。例如下面的示範過程。
>>> listx = [1,2,3,4,5,6,7] # 7 個元素
>>> listy = [2,3,4,5,6,7] # 6 個元素
>>> listz = [100,100,100,100] # 4 個元素
>>> list_result = map(lambda x,y,z : x**2 + y + z,listx, listy, listz)
>>> print(list(list_result))
[103, 107, 113, 121]
由此可以看出是由于 lambda 中的 z 參數,實際是使用了 listz, 而 listz 裡面隻有 4 個元素, 是以即使 listx 有 7 個元素, listy 有 6 個元素,也不會繼續執行了,隻執行了 4 個元素的的計算。
當在函數map()中傳入多個可疊代對象時,函數的參數必須提供足夠多的參數,保證每個可疊代對象同一索引的值均能正确傳入函數。例如下面的示範過程。
>>> a = map(ord,'abcd')
>>> list(a)
[97, 98, 99, 100]
>>> a = map(ord,'abcd','efg') #傳入兩個可疊代對象,是以傳入的函數必須能接收2個參數,ord不能接收2個參數,是以報錯
>>> list(a)
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
list(a)
TypeError: ord() takes exactly one argument (2 given)
>>> def f(a,b):
return a + b
>>> a = map(f,'abcd','efg') # f函數可以接受2個參數
>>> list(a)
['ae', 'bf', 'cg']
當傳入多個可疊代對象時,且它們元素長度不一緻時,生成的疊代器隻到最短長度。例如下面的示範過程。
>>> def f(a,b):
return a + b
>>> a = map(f,'abcd','efg') # 選取最短長度為3
>>> list(a)
['ae', 'bf', 'cg']