一、三元表达式、列表推导式、生成器表达式
1、三元表达式
name=input('姓名>>: ')
res='SB' if name == 'alex' else 'NB'
print(res)
2、列表推导式
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)优点:方便,改变了编程习惯,可称之为声明式编程
3、生成器表达式
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)优点:省内存,一次只产生一个值在内存中
二、递归与二分法
1、递归调用的定义
递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用
2、递归分为两个阶段:递推,回溯
salary(5)=salary(4)+300
salary(4)=salary(3)+300
salary(3)=salary(2)+300
salary(2)=salary(1)+300
salary(1)=100
salary(n)=salary(n-1)+300 n>1
salary(1) =100 n=1
def salary(n):
if n == 1:
return 100
return salary(n-1)+300
print(salary(5))
3、python中的递归效率低且没有尾递归优化
python中的递归效率低,需要在进入下一次递归时保留当前的状态
在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
但是python又没有尾递归,且对递归层级做了限制
4、总结递归的使用:
1)必须有一个明确的结束条件
2)每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3)递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
5、可以修改递归最大深度
import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000)
n=1
def test():
global n
print(n)
n+=1
test()
test()
虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归
6、二分法
想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模
1)实现类似于in的效果
l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
def search(num,l):
print(l)
if len(l) > 0:
mid=len(l)//2
if num > l[mid]:
#in the right
l=l[mid+1:]
elif num < l[mid]:
#in the left
l=l[:mid]
else:
print('find it')
return
search(num,l)
else:
#如果值不存在,则列表切为空
print('not exists')
return
search(100,l)
2)实现类似于l.index(30)的效果
l=[1,2,10,30,33,99,101,200,301,402]
def search(num,l,start=0,stop=len(l)-1):
if start <= stop:
mid=start+(stop-start)//2
print('start:[%s] stop:[%s] mid:[%s] mid_val:[%s]' %(start,stop,mid,l[mid]))
if num > l[mid]:
start=mid+1
elif num < l[mid]:
stop=mid-1
else:
print('find it',mid)
return
search(num,l,start,stop)
else: #如果stop > start则意味着列表实际上已经全部切完,即切为空
print('not exists')
return
search(301,l)
三、匿名函数
1、什么是匿名函数?
匿名就是没有名字
def func(x,y,z=1):
return x+y+z
匿名lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z
func(1,2,3)
#让其有名字就没有意义
2、有名字的函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
匿名函数:一次性使用,随时随时定义
应用:max,min,sorted,map,reduce,filter
四、内置函数
注意:内置函数id()可以返回一个对象的身份,返回值为整数。这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,不应该作为对身份的定义,即不够精准,最精准的还是以内存地址为准。is运算符用于比较两个对象的身份,等号比较两个对象的值,内置函数type()则返回一个对象的类型
更多内置函数:https://docs.python.org/3/library/functions.html?highlight=built#ascii
本文转自西鼠 51CTO博客,原文链接:http://blog.51cto.com/10630401/2056573,如需转载请自行联系原作者