天天看点

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']