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