迭代与函数

迭代与函数

迭代器

迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的_next_方法。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。
  总结:迭代器具有能使用next(f)函数或f.next()方法依次访问数据的功能,迭代器通过iter(f)函数或者f.__iter()__方法返回本身,即:
>>> iter(f)is f
True

迭代器协议

对象需要提供__next()__方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。

迭代器对象与可迭代对象

  • 迭代器对象
    实现了迭代器协议的对象。
    迭代器对象也是可迭代对象,迭代器对象具有__next__()方法和__iter__()方法。
    例如文件为迭代器对象
>>> f=open(r'C:\Users\Administrator\Desktop\shici.txt','w',encoding='utf8')
>>> f.write('你好\n世界\npython\n')
13
>>> f.close()
>>> f=open(r'C:\Users\Administrator\Desktop\shici.txt',encoding='utf8')
>>> iter(f) is f
True
>>> f.__next__()
'你好\n'
>>> next(f)
'世界\n'
>>> f.__next__()
'python\n'
>>> f.__next__()
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    f.__next__()
StopIteration
  • 可迭代对象
    如果一个对象拥有__iter__()方法,其是可迭代对象。__iter__方法返回的是当前对象的迭代器类的实例。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。

可迭代对象可以使用内建函数iter()或__iter__()方法,把该对象变成迭代器对象。举例说明如下
>>> lt=['1','2','3']
判断列表lt是否为迭代器对象
>>> iter(lt) is lt
False
使用iter()函数或者lt.__inter__()方法将列表变为迭代器对象
>>> iterator=iter(lt)
>>> iter(iterator) is iterator
True
使用next()函数或iterator.__next__()方法访问数据
>>> iterator.__next__()
'1'
>>> next(iterator)
'2'
>>> iterator.__next__()
'3'
>>> iterator.__next__()
Traceback (most recent call last): File "<pyshell#12>", line 1, in <module> iterator.__next__()
StopIteration
  
  在使用迭代工具如for,map时,对可迭代对象自动使用了__iter__()方法,将可迭代对象变为迭代器对象。

内置可迭代对象

  • range()
    range(起始值,终值,步长)
for i in range(0,5,2):
	print(i)
0
2
4
  • zip()
    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象的迭代器。
>>> ls1=[1,2,3,4]
>>> ls2=['a','b','c']
>>> m = zip(ls1,ls2)
>>> m
<zip object at 0x000001CE37490548>
>>> for i in m:
	print(i)
(1, 'a')
(2, 'b')
(3, 'c')

zip(*)与zip相反用于解压元组对象

>>> a1,a2 = zip(*m)
>>> a1
(1, 2, 3)
>>> a2
('a', 'b', 'c')
  • map()函数
    map() 会根据提供的函数对指定序列做映射。

map(function, iterable, …)
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的迭代器对象。
>>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))# 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
>>>list(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
[3, 7, 11, 15, 19]

  • filter()函数
    filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

filter(function, iterable)
该接收两个参数,第一个为函数,第二个为可迭代对象,可迭代对象的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的生成新的迭代器对象。

>>> lt= filter(lambda x:x%2==0,range(10))
>>> lt
<filter object at 0x000001CE37478E10>
>>> lt.__next__()
0
>>> list(lt)
[2, 4, 6, 8]
  • reduce()
    reduce() 函数会对参数序列中元素进行累积操作。
    reduce(function, iterable[, initializer])
    对可迭代对象使用函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
    >>> from functools import reduce
    reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
    15

函数

函数是一段具有特定功能的、可重用的语句组,通过函数名来表示和调用。

作用

  • 增加代码复用
  • 过程分解降低编程难度
  • 降低代码维护难度

定义

  • def 函数名(形参…):函数体

调用

  • 函数名(实参)

函数的参数传递

1、可选参数的传递
可选参数一般在非可选参数后面,定义函数时,先给出非可选参数,在给出可选参数及对应的默认值。

>>> def multiply(x,y=10):
	    print(x*y)
>>> multiply(99)
990
>>> multiply(99,2)
198

当函数被调用时,如果没有传入可选参数的值,则用定义函数时的默认值代替。

2、参数名称传递
函数调用时,默认采用按照顺序的方式传递给函数,采用参数名称传递方式不需要保持参数传递的顺序,只需要对每个必要参数赋值即可。

>>> def multiply(x,y=10):
	    print(x*y)
>>> multiply(y=5,x=20)
100

变量作用域

在python中作用域规则可以简单的归纳为LEGB原则,也就是说,对于一个变量name,首先会从当前的作用域开始查找,如果它不在函数里那就从global开始,没找到就查找builtin作用域,如果它位于函数中,就先从local作用域查找,接着如果当前的函数是一个闭包,那么就查找外层闭包的作用域,也就是规则中的E,接着是global和builtin,如果都没找到name这个变量,则抛出NameError。

  • Built-in内置函数
    例如len(),sorted(),print()函数

  • 全局变量
    全局变量指在函数之外定义的变量,在函数内部使用时需要使用保留字global声明。

i=0
def f():
  	global i
  	print(i)
  	i += 1
 	print(i)
f()
>>>0
1

函数内部不对同名变量进行赋值操作时,会自动找寻到上一级(L→E→G)同名变量。未加说明而在函数内对一个变量赋值,那么就认为你定义了一个局部变量,从而把外部的同名对象屏蔽了。如

i=0
def f():
  	print(i)
f()
>>>0
  • enclosure闭包作用域变量
    使用nonlocal关键字调用
def closure():
    count = 0
  	def func():
   # 要使用nonlocal关键字声明
	    nonlocal count
   		count += 1
    	print(f'I have be called {count} times')
  	return func
>>> f=closure()
>>> f()
I have be called 1 time
>>> f()
I have be called 2 times
  • local局部变量
    局部变量是指在函数内部定义的变量,仅在函数内部有效,当函数退出时变量将不复存在。
>>> def fun(x):
		i=x**2
		return i

>>> fun(2)
4
>>> i
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    i
NameError: name 'i' is not defined

参数

  • 不可变类型,传递副本给函数,函数内操作不影响原始值
def change_number(x):
    x+=10

a=5
print(a)
change_number(a)
print(a)
>>>
5
5
  • 可变类型,传递地址给函数,函数内操作可能影响原始值
def change_list(l):
    l[0]=10

l=['wo','shi','shei']
print(l)
change_list(l)
print(l)
>>>
['wo', 'shi', 'shei']
[10, 'shi', 'shei']

常用推导式写法

ls = [1,2,3]
a=[i for i in ls if i>1] #只有if条件在for后面
print(a)
b =[i if i>1 else 0 for i in ls] #if,else存在的时候都在for前面
print(b)

[2, 3]
[0, 2, 3]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值