热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

7.内置函数、作用域、闭包、递归

1.几个可能用到的内置函数2.函数内变量的作用域3.内嵌函数和闭

1.常见的内置函数

常见的内置函数:
查看内置函数:
print(dir(__builtins__))
常见函数

type 查看对象类型
len 求长度
min 求最小值
max 求最大值
sorted 排序
reversed 反向
sum 求和

print  打印

help 帮助

id 查看对象内存地址

range 从起始值到结束值按照一定步长的序列

进制转换函数:
bin() 转换为二进制
oct() 转换为八进制
hex() 转换为十六进制
ord() 将字符转换成对应的ASCII码值
chr() 将ASCII码值转换成对应的字符
补充:
1.enumerate() #返回一个可以枚举的对象
2.filter() #过滤器
3.map() #加工。对于参数iterable中的每个元素都应用fuction函数,并返回一个map对象
4.zip() #将对象逐一配对

example:

li =[1,2,3,4]
sum(li) #10

abs(-12) #绝对值 12

round(1.4) #四舍五入 1
round(1.445,2) #保留两位小数 1.45

bin(5)  #二进制 0101

oct(8)  #八进制  %o
hex(10) #16进制 A

ord(a) #将字符转换成对应的ASCII码值
ord(A)
chr(65) #将ASCII码值转换成对应的字符


#1.enumerate   #返回一个可以枚举的enumerate对象  (index,value)
li = [a,c,b] 
list(enumerate(li)) # 通过list转换成列表 [(0, ‘a‘), (1, ‘c‘), (2, ‘b‘)]

dict(enumerate(li))  #也可以通过dict转成字典 {0: ‘a‘, 1: ‘c‘, 2: ‘b‘}

#注意  集合 ,字典,是无序的,没用索引。 通过enumerate可以返回(伪索引,value)
se = {1,2,3,asd,5}

list(enumerate(se))  # [(0, 1), (1, ‘asd‘), (2, 2), (3, 3), (4, 5)]
dict(enumerate(se)) # {0: 1, 1: ‘asd‘, 2: 2, 3: 3, 4: 5}


#2.filter() #过滤器,生成一个当参数传入函数结果为True的可迭代对象
li =[1,2,3,6,7,8]
def test(x):
    return x>5

list(filter(test,li)) #[6, 7, 8]  
#lambda 凡是可以用到简单函数地方,都可以用lambda
list(filter(lambda x:x>5,li)) #[6, 7, 8]  


# 3.map() #加工
li =[1,2,3,6,7,8]

list(map(str,li))   #把各个元素转换成字符串 [‘1‘, ‘2‘, ‘3‘, ‘6‘, ‘7‘, ‘8‘]

#每一个元素加一个 1
list(map(lambda x:x+1,li)) # [2, 3, 4, 7, 8, 9]

# zip() #将对象逐一配对,按照短序列来生成
li2 =[1,2,3]
tu = (a,b,c,e)
list(zip(li2,tu))  # [(1, ‘a‘), (2, ‘b‘), (3, ‘c‘)]
dict(zip(li2,tu))  # {1: ‘a‘, 2: ‘b‘, 3: ‘c‘}

2.函数内变量的作用域

变量的作用域与其定义的方式有关:
局部变量: 变量在函数内部定义,则变量的作用域在函数内部
全局变量:变量在函数外部定义的,则变量的作用域是全局

global:用来在函数或其他局部作用域中,声明全局变量。 (作用于全局)
nonlocal:用来在函数或其他作用域中,声明外层(非全局)变量。(作用于局部)

使用global情况:
全局变量可以在函数内部访问,但是不能改变
如果在函数内部想修改全局变量,可以用 global 来修饰变量

局部变量只能在局部进行访问和修改。
如果在函数外部,想访问局部变量,也可以用 global,将局部变量声明为全局变量

使用nonlocal的情况:
当里层局部,需要修改外层局部时,需要使用nonlocal。 (如嵌套函数)


总结:
global :函数中,需要修改全局变量时,用global
nonlocal:当里层局部,需要修改外层局部时,需要使用nonlocal。
(局部调用局部,使用nonlocal)

‘‘‘
全局变量可以在函数内部访问,但是不能改变
如果在函数内部想修改全局变量,可以用 global 来修饰变量

‘‘‘

a = 10 #全局变量
def test1():
    b = 5 #局部变量
    print(局部访问全局变量 a:,a)  #局部可以访问,全局变量
    #a +=1   #全局变量可以在函数内部访问,但是不能改变
 


def test2():
    global a  #全局声明
    a +=1
    print(内部修改全局变量 a:,a)



def test3():  # global 只对当前函数起作用
    #global a
    a +=1
    print(teat3修改全局 a,a)


‘‘‘
局部变量只能在局部进行访问和修改。
如果在函数外部,想访问局部变量,也可以用 global,将局部变量声明为全局变量
‘‘‘
def test4():
    global b 
    b = 4
    b+=1
    a = 21
    print(局部变量 b:,b)




## 使用nonlocal的情况

#内嵌函数

def test5():
    c = 2
    print(局部外层 c,c)
    def test6():
        d = 5
        print(局部里层 d,d)
    test6()


# nonlocal


c = 11
def test7():
    c = 2       #声明外层(非全局)变量
    print(局部外层 c,c)
    def test8():
        d = 5
        print(局部里层 d,d)
        nonlocal c 
        #global c   
        c += 1   #当里层局部,需要修改外层局部时
        print(当里层局部,需要修改外层局部 C ,c)
    test8()

3.内嵌函数和闭包

内嵌函数: 在函数内部定义函数,就是函数里面嵌套函数

闭包:一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。(但是B函数,一定要是嵌套在函数A里面) 。你在调用函数A的时候传递的参数就是自由变量。

总结:一个函数里面嵌套一个函数,调用外面这个函数,就返回里面嵌套的函数。

example:

def test9(name):
    
   def test10(age):
       print(name,name,age,age)
       
   return test10

f10 = test9(jianeng)
f10 (18)
问题:以下函数算不算闭包呢?
def test12():
    print(12)
    def test13():
        print(13)
        def test14():
            print(14) 
        return test14()
    return test13()
 

4.递归函数

递归: 函数调用自己本身

递归的核心:
1.递归推导式
2.递归终止条件

不过虽然递归很方便,但是尽量少用,以防栈溢出,而且会计算效率不高。

‘‘‘
例题:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。
       问第4个人岁数,他说比第3个人大2岁。
       问第三个人,又说比第2人大两岁。
       问第2个人,说比第一个人大两岁。
       最后问第一个人,他说是10岁。
       请问第五个人多少岁?
‘‘‘

  n1      n2        n3         n4      n5    

#   10    n1 +2    n2 +2      n3 +2       n4+2


#for  循环
def age(n):
    age = 10
    for i in range(1,n):
        age = age +2
    print(最后一个人,是%s 岁%age)



### 递归
def age2(n):
    if n == 1:
        return 10
    else:
        return age2(n-1) +2
##要计算age2(n)的值,程序会先去计算age2(n-1)的值,要计算 age2(n-1)的值,程序要计算age2(n-2)的值...直到n==1的时候,程序算出了age2(1)的值,再把值拿到age2(2)里面...以此类推,算出age2(n)

### 阶层   1!=1*1   2!=2*1  3!=3*2*1   4!=4*3*2*1

#          1!     2! =2*1! 3!=3*2!   4! =4 *3!


#推导式 : n! = n * (n-1) !
#终止条件:  n == 1   return 1


def jie(n):
    if n ==1:
        return 1
    else:
        return jie(n-1) *n


5.作业

1、定义一个函数,输入一个序列(序列元素是同种类型),判断序列是顺序还是逆序,顺序输出UP,逆序输出DOWN,否则输出None (sorted)

技术分享图片技术分享图片
def judge_seq(seq):
    se = list(seq)
    print(se)
    if sorted(se) == se:
        return up
    elif sorted(se,reverse=True)== se:  #降序逆序
        return DOWM
    else:   # sorted(se) != se
        return None
View Code

2、写一个函数,对列表li = [9,8,3,2,6,4,5,7,1],进行从小到大的排序,最后返回li(用冒泡排序写)

技术分享图片技术分享图片
li=[9,8,7,6,5,4,3,2,1]
def li_sort(li):
    print(li)
    for j in range(len(li)-1):
        for i in range(len(li)-1):
            if li[i] > li[i+1]:
                li[i],li[i+1] = li[i+1],li[i]
    print(li)
View Code

3、一个列表,有4个由数字组成的长度为4的元组,对这四个元组,按每个元组的第2个数字大小排序

技术分享图片技术分享图片
lis = [(2,3,4,5),(1,8,6,7),(6,0,1,9),(9,6,3,1)]

lis.sort(key=lambda a:a[1])  
View Code

4、思考题:有一个名为list_apd的函数,如下所示,请你多次调用这个函数,对比返回值,是否与你预期的一致?

def list_apd(b,a=[]):   
    a.append(b)
    return a
技术分享图片技术分享图片
‘‘‘不一致,比如当我第一次调用 list_apd(1)时,返回为[1],再次调用list_apd(1),
返回值却是 [1,1],这与我所想的不一样,如果想改善应该这么写‘‘‘


def list_apd(b,a=None):
    if a = None:
        a=[]
    a.append(b)
    return a

#默认参数 必须指向不可变对象,防止逻辑错误
View Code

7.内置函数、作用域、闭包、递归


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
author-avatar
ChrisBao
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有