三元表达式列表推导式生成器表达式递归匿名函数内置函数

Posted shaomz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三元表达式列表推导式生成器表达式递归匿名函数内置函数相关的知识,希望对你有一定的参考价值。

介绍

三元表达式、列表推导式、生成器表达式

递归与二分法

匿名函数

一、三元表达式、列表推导式、生成器表达式

  1.1 三元表达式(三目运算)

格式:
[为真时的结果 if 判定条件 else 为假时的结果 ] 

name=input(姓名>>: ) res=SB if name == alex else NB print(res)

如果输入的是alex 出来的就是SB

  1.2 列表推导式

格式:[表达式 for 变量 in 列表]    或者  [表达式 for 变量 in 列表 if 条件]    
列表推导式(list comprehension)是利用其他列表创建新列表(类似于数学术语中的集合推导式)的一种方法。它的工作方式类似于for循环,也很简单:
# l=[] # for i in range(1,11): # res=‘egg‘+str(i) # l.append(res) # # print(l) # l=[‘egg‘+str(i) for i in range(1,11)] # print(l) # l1=[‘egg‘+str(i) for i in range(1,11) if i >= 6] # print(l1) # l1=[] # for i in range(1,11): # if i >= 6: # l1.append(‘egg‘+str(i))

  1.3 生成器表达式

#1、把列表推导式的[]换成()就是生成器表达式

#2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
>>> chicken=(鸡蛋%s %i for i in range(0,,100000000000000))
>>> chicken
<generator object <genexpr> at 0x10143f200>
>>> next(chicken)
鸡蛋0
>>> list(chicken) #因chicken可迭代,因而可以转成列表
[鸡蛋1, 鸡蛋2, 鸡蛋3, 鸡蛋4,]

#3、优点:省内存,一次只产生一个值在内存中

  1.4 小练习

技术分享图片
1、将names=[egon,alex_sb,wupeiqi,yuanhao]中的名字全部变大写

2、将names=[egon,alex_sb,wupeiqi,yuanhao]中以sb结尾的名字过滤掉,然后保存剩下的名字长度

3、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)

4、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数)
5.为何报错?
with open(a.txt) as f:
    g=(len(line) for line in f)
print(sum(g)) #为何报错

6、文件shopping.txt内容如下
    mac,20000,3
    lenovo,3000,10
    tesla,1000000,10
    chicken,200,1
求总共花了多少钱?

打印出所有商品的信息,格式为[{name:xxx,price:333,count:3},...]

求单价大于10000的商品信息,格式同上
小练习
技术分享图片
#题目一
names=[egon,alex_sb,wupeiqi,yuanhao]
names=[name.upper() for name in names]

#题目二
names=[egon,alex_sb,wupeiqi,yuanhao]
names=[len(name) for name in names if not name.endswith(sb)]

#题目三
with open(a.txt,encoding=utf-8) as f:
    print(max(len(line) for line in f))

#题目四
with open(a.txt, encoding=utf-8) as f:
    print(sum(len(line) for line in f))
    print(sum(len(line) for line in f)) #求包换换行符在内的文件所有的字符数,为何得到的值为0?
    print(sum(len(line) for line in f)) #求包换换行符在内的文件所有的字符数,为何得到的值为0?

#题目五(略)

#题目六:每次必须重新打开文件或seek到文件开头,因为迭代完一次就结束了
with open(a.txt,encoding=utf-8) as f:
    info=[line.split() for line in f]
    cost=sum(float(unit_price)*int(count) for _,unit_price,count in info)
    print(cost)


with open(a.txt,encoding=utf-8) as f:
    info=[{
        name: line.split()[0],
        price: float(line.split()[1]),
        count: int(line.split()[2]),
    } for line in f]
    print(info)


with open(a.txt,encoding=utf-8) as f:
    info=[{
        name: line.split()[0],
        price: float(line.split()[1]),
        count: int(line.split()[2]),
    } for line in f if float(line.split()[1]) > 10000]
    print(info)
View Code

二、递归与二分法

  2.1 递归调用的定义

#递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用

#递归调用:在调用一个函数的过程中,直接或者间接又调用该函数本身,称之为递归调用

  2.2 递归的两个阶段 递推,回溯

技术分享图片
# import sys
# print(sys.getrecursionlimit())
# sys.setrecursionlimit(2000)
# print(sys.getrecursionlimit())

# def func(n):
#     print(‘---->‘,n)
#     func(n+1)
#
# func(0)


# def bar():
#     print(‘from bar‘)
#     func()
#
# def func():
#     print(‘from func‘)
#     bar()
#
# func()


# age(5) = age(4) + 2
# age(4) = age(3) + 2
# age(3) = age(2) + 2
# age(2) = age(1) + 2
#
# age(1) = 18

# age(n)=age(n-1)+2 # n > 1
# age(1) = 18 #n = 1


# def age(n):
#     if n == 1:
#         return 18
#     return age(n-1) + 2
#
# res=age(5)
# print(res)


# l=[1,[2,[3,[4,[5,[6,[7,]]]]]]]
#
#
# def func(l):
#     for item in l:
#         if type(item) is list:
#             func(item)
#         else:
#             print(item)



# def func():
#     print(‘===>‘)
#     func()
#
# func()
View Code

  2.3 python中的递归效率低且没有尾递归优化

#python中的递归
python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,
尾递归优化:http://egon09.blog.51cto.com/9161406/1842475 但是python又没有尾递归,且对递归层级做了限制 #总结递归的使用: 1. 必须有一个明确的结束条件 2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少 3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,
栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

  2.4 递归深度最大的修改

简单说就是可以递归多少层,python 默认是1000

import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000) 



n=1
def test():
    global n
    print(n)
    n+=1
    test()

test()

虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归

  2.5 二分法

    想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表

def binary_search(l,num):
    print(l)
    if len(l) == 0:
        print(not exists)
        return
    mid_index=len(l) // 2
    if num > l[mid_index]:
        #往右找
        binary_search(l[mid_index+1:],num)

    elif num < l[mid_index]:
        #往左找
        binary_search(l[0:mid_index],num)
    else:
        print(find it)

# binary_search(l,301)
binary_search(l,302)

三、匿名函数

  3.1 什么是匿名函数

    格式: 使用 lambda  函数体……

匿名就是没有名字
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)
#让其有名字就没有意

  3.2  有名与匿名的对比

#有名函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能

匿名函数:一次性使用,随时随时定义
常用函数:max,min,sorted,map,reduce,filter
max:max() 方法返回给定参数的最大值,参数可以为序列。
min:min() 方法返回给定参数的最小值,参数可以为序列。
sorted:排序
map:map() 会根据提供的函数对指定序列做映射。
reduce:reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复
调用函数f,并返回最终结果值。 filter:filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,
返回由符合条件元素组成的新list。
使用过程见下文
技术分享图片
#max,min,sorted,map,reduce,filter
# salaries={
#     ‘egon‘:3000,
#     ‘alex‘:100000000,
#     ‘wupeiqi‘:10000,
#     ‘yuanhao‘:2000
# }
# print(max(salaries))

# s=‘hello‘
# l=[1,2,3]
# g=zip(s,l)
# # print(g)
# print(list(g))

# g=zip(salaries.values(),salaries.keys())
# # print(list(g))
# print(max(g))

# def func(k):
#     return salaries[k]

# print(max(salaries,key=func)) #key=func(‘egon‘)

# print(max(salaries,key=lambda k:salaries[k])) #key=func(‘egon‘)
# print(min(salaries,key=lambda k:salaries[k])) #key=func(‘egon‘)

#sorted
# salaries={
#     ‘egon‘:3000,
#     ‘alex‘:100000000,
#     ‘wupeiqi‘:10000,
#     ‘yuanhao‘:2000
# }
# print(sorted(salaries,key=lambda k:salaries[k]))
# print(sorted(salaries,key=lambda k:salaries[k],reverse=True))


#map,reduce,filter
# names=[‘alex‘,‘wupeiqi‘,‘yuanhao‘]
# l=[]
# for name in names:
#     res=‘%s_SB‘ %name
#     l.append(res)
#
# print(l)

# g=map(lambda name:‘%s_SB‘ %name,names)
# # print(g)
# print(list(g))


# names=[‘alex_sb‘,‘wupeiqi_sb‘,‘yuanhao_sb‘,‘egon‘]
# g=filter(lambda x:x.endswith(‘sb‘),names)
# print(g)
# print(list(g))



#from functools import reduce
#print(reduce(lambda x,y:x+y,range(1,101),100))
常用函数

四 内置函数

#注意:内置函数id()可以返回一个对象的身份,返回值为整数。这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,不应该作为对身份的定义,
即不够精准,最精准的还是以内存地址为准。is运算符用于比较两个对象的身份,等号比较两个对象的值,内置函数type()则返回一个对象的类型
#更多内置函数:https://docs.python.org/3/library/functions.html?highlight=built#ascii

技术分享图片

技术分享图片
#字符串可以提供的参数 ‘s‘ None
>>> format(some string,s)
some string
>>> format(some string)
some string

#整形数值可以提供的参数有 ‘b‘ ‘c‘ ‘d‘ ‘o‘ ‘x‘ ‘X‘ ‘n‘ None
>>> format(3,b) #转换成二进制
11
>>> format(97,c) #转换unicode成字符
a
>>> format(11,d) #转换成10进制
11
>>> format(11,o) #转换成8进制
13
>>> format(11,x) #转换成16进制 小写字母表示
b
>>> format(11,X) #转换成16进制 大写字母表示
B
>>> format(11,n) #和d一样
11
>>> format(11) #默认和d一样
11

#浮点数可以提供的参数有 ‘e‘ ‘E‘ ‘f‘ ‘F‘ ‘g‘ ‘G‘ ‘n‘ ‘%‘ None
>>> format(314159267,e) #科学计数法,默认保留6位小数
3.141593e+08
>>> format(314159267,0.2e) #科学计数法,指定保留2位小数
3.14e+08
>>> format(314159267,0.2E) #科学计数法,指定保留2位小数,采用大写E表示
3.14E+08
>>> format(314159267,f) #小数点计数法,默认保留6位小数
314159267.000000
>>> format(3.14159267000,f) #小数点计数法,默认保留6位小数
3.141593
>>> format(3.14159267000,0.8f) #小数点计数法,指定保留8位小数
3.14159267
>>> format(3.14159267000,0.10f) #小数点计数法,指定保留10位小数
3.1415926700
>>> format(3.14e+1000000,F)  #小数点计数法,无穷大转换成大小字母
INF

#g的格式化比较特殊,假设p为格式中指定的保留小数位数,先尝试采用科学计数法格式化,得到幂指数exp,如果-4<=exp<p,则采用小数计数法,并保留p-1-exp位小数,否则按小数计数法计数,并按p-1保留小数位数
>>> format(0.00003141566,.1g) #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点
3e-05
>>> format(0.00003141566,.2g) #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留1位小数点
3.1e-05
>>> format(0.00003141566,.3g) #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留2位小数点
3.14e-05
>>> format(0.00003141566,.3G) #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点,E使用大写
3.14E-05
>>> format(3.1415926777,.1g) #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留0位小数点
3
>>> format(3.1415926777,.2g) #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留1位小数点
3.1
>>> format(3.1415926777,.3g) #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留2位小数点
3.14
>>> format(0.00003141566,.1n) #和g相同
3e-05
>>> format(0.00003141566,.3n) #和g相同
3.14e-05
>>> format(0.00003141566) #和g相同
3.141566e-05

format(了解即可)
format
技术分享图片
字典的运算:最小值,最大值,排序
salaries={
    egon:3000,
    alex:100000000,
    wupeiqi:10000,
    yuanhao:2000
}

迭代字典,取得是key,因而比较的是key的最大和最小值
>>> max(salaries)
yuanhao
>>> min(salaries)
alex

可以取values,来比较
>>> max(salaries.values())
>>> min(salaries.values())
但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
>>> max(salaries,key=lambda k:salary[k])
alex
>>> min(salaries,key=lambda k:salary[k])
yuanhao



也可以通过zip的方式实现
salaries_and_names=zip(salaries.values(),salaries.keys())

先比较值,值相同则比较键
>>> max(salaries_and_names)
(100000000, alex)


salaries_and_names是迭代器,因而只能访问一次
>>> min(salaries_and_names)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence



sorted(iterable,key=None,reverse=False)

!!!lambda与内置函数结合使用!!!
lambda与内置函数结合使用!
技术分享图片
#1、语法
# eval(str,[,globasl[,locals]])
# exec(str,[,globasl[,locals]])

#2、区别
#示例一:
s=1+2+3
print(eval(s)) #eval用来执行表达式,并返回表达式执行的结果
print(exec(s)) #exec用来执行语句,不会返回任何值
‘‘‘
None
‘‘‘

#示例二:
print(eval(1+2+x,{x:3},{x:30})) #返回33
print(exec(1+2+x,{x:3},{x:30})) #返回None

# print(eval(‘for i in range(10):print(i)‘)) #语法错误,eval不能执行表达式
print(exec(for i in range(10):print(i)))

eval与exec
eval与exec
技术分享图片
compile(str,filename,kind)
filename:用于追踪str来自于哪个文件,如果不想追踪就可以不定义
kind可以是:single代表一条语句,exec代表一组语句,eval代表一个表达式
s=for i in range(10):print(i)
code=compile(s,‘‘,exec)
exec(code)


s=1+2+3
code=compile(s,‘‘,eval)
eval(code)

complie(了解即可)
complie
1、文件内容如下,标题为:姓名,性别,年纪,薪资

egon male 18 3000
alex male 38 30000
wupeiqi female 28 20000
yuanhao female 28 10000

要求:
从文件中取出每一条记录放入列表中,
列表的每个元素都是{name:egon,sex:male,age:18,salary:3000}的形式

2 根据1得到的列表,取出薪资最高的人的信息
3 根据1得到的列表,取出最年轻的人的信息
4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
5 根据1得到的列表,过滤掉名字以a开头的人的信息
6 使用递归打印斐波那契数列(前两个数的和得到第三个数,如:0 1 1 2 3 4 7...)

7 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
技术分享图片
#1
with open(db.txt) as f:
    items=(line.split() for line in f)
    info=[{name:name,sex:sex,age:age,salary:salary}           for name,sex,age,salary in items]

print(info)
#2
print(max(info,key=lambda dic:dic[salary]))

#3
print(min(info,key=lambda dic:dic[age]))

# 4
info_new=map(lambda item:{name:item[name].capitalize(),
                          sex:item[sex],
                          age:item[age],
                          salary:item[salary]},info)

print(list(info_new))

#5
g=filter(lambda item:item[name].startswith(a),info)
print(list(g))

#6
#非递归
def fib(n):
    a,b=0,1
    while a < n:
        print(a,end= )
        a,b=b,a+b
    print()

fib(10)
#递归
def fib(a,b,stop):
    if  a > stop:
        return
    print(a,end= )
    fib(b,a+b,stop)

fib(0,1,10)


#7
l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]

def get(seq):
    for item in seq:
        if type(item) is list:
            get(item)
        else:
            print(item)
get(l)
View Code

 











以上是关于三元表达式列表推导式生成器表达式递归匿名函数内置函数的主要内容,如果未能解决你的问题,请参考以下文章

三元表达式列表推导式生成器表达式递归匿名函数内置函数

三元表达式列表推导式生成器表达式递归匿名函数内置函数

三元表达式列表推导式生成器表达式递归匿名函数内置函数

三元表达式列表推导式生成器表达式递归内置函数匿名函数

函数之三元表达式,递归,匿名函数,内置函数

函数的递归,二分法,三元表达式,列表生成式,字典生成式,匿名函数,内置方法