天天看點

Python标準内置函數(36-40)

1.36  函數iter()

在Python程式中,使用函數iter()的文法格式如下所示。

iter(object[, sentinel])
           
  1. object:支援疊代的集合對象;
  2. 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, ...)
           
  1. function:函數,有兩個參數;
  2. 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']