Python开发【第5篇】:Python开发系列之函数之三元表达式、列表推导式、生成器表达式、递归、 迭代器和生成器
三元表达式
name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' print(res)
列表推导式
#1、示例 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s' %i) egg_list=['鸡蛋%s' %i for i in range(10)] #2、语法 [expression for item1 in iterable1 if condition1 for item2 in iterable2 if condition2 ... for itemN in iterableN if conditionN ] 类似于 res=[] for item1 in iterable1: if condition1: for item2 in iterable2: if condition2 ... for itemN in iterableN: if conditionN: res.append(expression) #3、优点:方便,改变了编程习惯,可称之为声明式编程 ——————————————————————— 举例一 y=2 #for i in range(100): # print(i*y) #列表推导式是for循环的简写 l=[i*y for i in range(100)] 举例二 l=[{'name':'v1','age':'22'},{'name':'v2'}] # for dic in l: # print(dic['name']) name_list=[dic['name'] for dic in l] print(name_list)
列表推导式 # ======一层循环====== l = [i*i for i in range(1,10)] print(l) # 上面的列表推倒式就相当于下面的 l = [] for i in range(1,10): l.append(i*i) print(l) l = [] # ======多层循环======== # 1.列表推倒式 l = [i*j for i in range(1,10) for j in range(1,10)] print(l) # 2.循环 l = [] for i in range(1,10): for j in range(1,10): s = i*j l.append(s) print(l)
生成器表达式
#1、把列表推导式的[]换成()就是生成器表达式 #2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性 >>> chicken=('鸡蛋%s' %i for i in range(5)) >>> chicken <generator object <genexpr> at 0x10143f200> >>> next(chicken) '鸡蛋0' >>> list(chicken) #因chicken可迭代,因而可以转成列表 ['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',] #3、优点:省内存,一次只产生一个值在内存中 ——————————————————————— l=[{'name':'v1','age':'22'},{'name':'v2'}] name_list=(dic['name'] for dic in l)#把列表推导式的[]改成() print(name_list)#取出的是一个生成器,而不是要取得值,所以得加上next print(next(name_list)) print(next(name_list)) # print(next(name_list))
递归
一、递归的定义
1.什么是递归:在一个函数里在调用这个函数本身
2.最大递归层数做了一个限制:998,但是也可以自己限制,下面验证998,998之后就会开始报错:
def foo(n): print(n) n += 1 foo(n) if __name__ == '__main__': foo(1) ps: 最大层数限制是python默认的,可以做修改,但是不建议你修改。(因为如果用998层递归都没有解决的问题要么是不适合使用递归来解决问题,要么就是你的代码太烂了)
import sys sys.setrecursionlimit(10000000)#修改递归层数 n=0 def f(): global n n+=1 print(n) f() f() 我们可以通过以上代码,导入sys模块的方式来修改递归的最大深度。 sys模块:所有和python相关的设置和方法
4.结束递归的标志:return 5.递归解决的问题就是通过参数,来控制每一次调用缩小计算的规模 6.使用场景:数据的规模在减少,但是解决问题的思路没有改变 7.很多排序算法会用到递归
二、递归小应用
1.下面我们来猜一下小明的年龄 小明是新来的同学,丽丽问他多少岁了。 他说:我不告诉你,但是我比滔滔大两岁。 滔滔说:我也不告诉你,我比晓晓大两岁 晓晓说:我也不告诉你,我比小星大两岁 小星也没有告诉他说:我比小华大两岁 最后小华说,我告诉你,我今年18岁了 这个怎么办呢?当然,有人会说,这个很简单啊,知道小华的,就会知道小星的,知道小星的就会知道晓晓的,以此类推,就会知道小明的年龄啦。这个过程已经非常接近递归的思想了。 小华 18+2 小星 20+2 晓晓 22+2 滔滔 24+2 小明 26+2 上面的图我们可以用个序号来表示吧 age(5) = age(4)+2 age(4) = age(3) + 2 age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 18 代码实现结果: def age(n): if n == 1: return 18 else: return age(n - 1) + 2 ret=age(6) print(ret)
二分法请参考:http://www.cnblogs.com/haiyan123/p/7263707.html
迭代器和生成器
一、可迭代协议:可以被迭代要满足要求的就叫做可迭代协议。内部实现了__iter__方法
iterable:可迭代的------对应的标志
什么叫迭代?:一个一个取值,就像for循环一样取值
字符串,列表,元组,集合,字典都是可迭代的
二、迭代器协议:内部实现了__iter__,__next__方法
迭代器大部分都是在python的内部去使用的,我们直接拿来用就行了
迭代器的优点:如果用了迭代器,节约内存,方便操作
dir([1,2].__iter__())是列表迭代器中实现的所有的方法,而dir([1,2])是列表中实现的所有方法,都是以列表的方式返回给我们,为了方便看清楚,我们把他们转换成集合,然后取差集,然而,我们看到列表迭代器中多出了三个方法,那么这三个方法都分别是干什么的呢? 1 print(dir([1,2].__iter__()))#查看列表迭代器的所有方法 2 print(dir([1,2]))#查看列表的所有方法 3 print(set(dir([1,2].__iter__()))-set(dir([1,2]))) iter_l=[1,2,3,4,5,6].__iter__() print(iter_l.__length_hint__())#获取迭代器中元素的长度 # print(iter_l.__setstate__(4))#根据索引指定从哪里开始迭代 print(iter_l.__next__()) print(iter_l.__next__()) print(iter_l.__next__())#一个一个的取值 print(next(iter_l)) #next(iter_l)这个方法和iter_l.__next__()方法一样,推荐用next(iter_l)这个 l=[1,2,3,4,5] a=l.__iter__() # print(next(a)) # print(next(a)) # print(next(a)) # print(next(a)) # print(next(a)) # print(next(a)) #上面的列表长度只有5个,而你多打印了,就会报错。处理的情况如下,就不会报错了 while True: try: item=a.__next__() print(item) except StopIteration: # 异常处理 break
三、可迭代和迭代器的相同点:都可以用for循环
四、可迭代和迭代器的不同点:就是迭代器内部多实现了一个__next__方法
五、判断迭代器和可迭代的方法:
第一种:判断内部是不是实现了__next__方法 1 '__iter__' in dir(str)#如果__iter__在这个方法里面,就是可迭代的。 第二种: Iterable 判断是不是可迭代对象 Iterator 判断是不是迭代器 用法: from collections import Iterable from collections import Iterator #比如给一个字符串 s='abc' print(isinstance(s,Iterable))#isinstance判断类型的 print(isinstance(s,Iterator)) 判断range函数和map函数 map1=map(abs,[1,-2,3,-4]) print(isinstance(map1,Iterable)) print(isinstance(map1,Iterator))#map方法自带迭代器 s=range(100)#是一个可迭代的,但是不是迭代器 print(isinstance(s,Iterable)) print(isinstance(s,Iterator))
六、生成器函数:常规定义函数,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果。生成器的好处,就是一下子不会在内存中生成太多的数据
python中提供的生成器:1.生成器函数 2.生成器表达式
生成器的本质:就是一个迭代器
def func(): #这是一个简单的函数 a=1 return a print(func()) def func(): print('aaaaaaaaaaa') a = 1 yield a # 返回第一个值 print('bbbbbb') yield 12 # 返回第二个值 ret = func() # 得拿到一个生成器 # print(ret)#返回的是一个地址 print(next(ret))#取第一个值 print(next(ret))# 取第二个值 print(next(ret))# 取第三个值,会报错,因为没有yield第三个值
def func(): # for i in 'AB': # yield i yield from 'AB' yield from 'AB'就相当于上面的for循环,把循环简化了 yield from [1,2,3] g=func() print(list(g)) # print(next(g)) # print(next(g)) yield from
浙公网安备 33010602011771号