函数作用域和列表常用操作
Posted yuanjian6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数作用域和列表常用操作相关的知识,希望对你有一定的参考价值。
变量作用域?
- 变量有作用范围限制
- 分类,按作用域来分
- 全局( global ):在函数外部定义
- 局部( local):在函数内部定义
- 变量的作用范围
- 全局变量:在指定的整个范围内有效
- 全局变量在局部都可以使用(即函数内部可以方位函数外部定义函数变量)
- 局部变量在局部范围可以使用
- 局部变量在全局变量范围无法使用
- LEGB原则
- L (local)局部作用域
- E (Enclosing function locale)外部嵌套函数作用域
- G (Global module)函数定义所在模块作用域
- B (Buildin):python 内置模块的作用域
In [2]:
?x
# 认为a1是全局的
?
a1 = 100
def func():
print(a1)
print("I am in fun")
# a2 的作用范围是 func
a2 = 88
print(a2)
print(a1)
func()
# 提升局部变量为全局变量
?
- 使用 global
- 案例如下
提升局部变量为全局变量?
- 使用 global
- 案例如下
In [11]:
?
def func():
global b1
b1 = 100
print(b1)
print(a1)
print("I am in fun")
# a2 的作用范围是 func
a2 = 88
print(a1)
print(a1)
print(b1)
func()
## globals , locals函数
?
- 可以通过 globals和 locals 显示出全局变量和局部变量
- 参考以下案例
globals , locals函数?
- 可以通过 globals和 locals 显示出全局变量和局部变量
- 参考以下案例
In [12]:
# globals 和 locals
# globals 和 locals 叫内置函数
a = 1
b = 2
?
def func(c,d):
e = 112
print("Locals={0}".format(locals()))
print("Globals={0}".format(globals()))
func(30,50)
# eval()函数
?
- 把一个字符串当做一个表达式来执行,返回表达式执行后的结果
- 语法
eval( string_code, globals=None, locals=None)
# exe()函数
?
- 跟 eval 功能类似, 但是, 不返回结果
- 语法:
exec(string_code, globals=None, locals=None)
In [14]:
x = 20
y = 30
# 执行 x + y
# z = x + y
z1 = x + y
z2 = eval("")
?
print(z1)
print(z2)
In [17]:
x = 20
y = 30
# 执行 x + y
# z = x + y
z1 = x + y
# 1,注意字符串中引导的写法
# 2,比对 exec 执行结果和代码执行结果
z2 = exec("print(‘x+y:‘,x+y)")
?
print(z1)
print(z2)
# 递归函数
?
- 函数直接或者间接调用自身
- 优点 :简洁,理解容易
- 缺点: 对递归深度限制,消耗资源大
- python 对递归深度有限制,超过限制就会给你个超限报错
- 在写递归程序时,一定要有结束条件
递归函数?
- 函数直接或者间接调用自身
- 优点 :简洁,理解容易
- 缺点: 对递归深度限制,消耗资源大
- python 对递归深度有限制,超过限制就会给你个超限报错
- 在写递归程序时,一定要有结束条件
In [20]:
# 递归函数调用深度限制代码
?
x = 0
def func():
global x
x += 1
print(x)
# 函数自己调用自己
func()
# 调用函数
func()
In [24]:
# 斐波那契额数列
# 一列数字, 第一个值是1, 第二个值也是1, 从第三个数字开始,每一个数字等于前两个数值得和
# 数字公式为: f(1) = 1, f(2) = 1, f(n) = f(n-1) + f(n-2)
# 例如: 1,1,2,3,5,8,13.。。。。。。
?
?
# 下面求斐波那契数列函数有一定问题,比如 n 一开始就是负数,如何修正
# n 表示第 n 个斐波那契数列得值
def fib(n):
if n == 1:
return 1
if n == 2:
return 1
# 思考 :为甚后面 return 能正确执行, 而不用 else 语句
return fib(n-1) + fib(n-2)
?
print(fib(5))
print(fib(10))
In [29]:
# 1,创建空列表
l1 = []
# type 是内置函数,负责打印出变量得类型
print(type(l1))
print(l1)
?
# 2,创建带值得列表
l2 = [200]
print(type(l2))
print(l2)
?
?
# 3,创建列表,带多个值
l3 = [1,2,3,4,6]
print(type(l3))
print(l3)
?
?
?
# 4,使用 list
l4 = list()
print(type(l1))
print(l1)
# 列表常用操作
- 访问
- 使用下标操作(索引)
- 分片操作
- 对列表进行任意一段得截取
- L[:]
列表常用操作?
- 访问
- 使用下标操作(索引)
- 分片操作
- 对列表进行任意一段得截取
- L[:]
In [31]:
# 下标访问列表(按值得排列顺序来访问从 0 开始)
?
l = [1,2,3,4,6,7]
?
?
print(l[5])
print(l[3])
In [39]:
# 分片操作
# 注意截取范围:包含左标下标值不包含右边的下标值
l[1:5]
print(l[0:5])
?
?
# 下标值可以为空,如果不写,左边下标值默认为0,右边值为最大数加一,即表示截取到最后一个数据
print(l[:])
print(l[:6])
print(l[:3])
?
?
?
# 分片可以控制增长幅度,默认增长幅度为一
print(l[1:5:2])
?
# 下标可以超出一定得范围,超出后不再考虑多余下标内容
print(l[2:10])
?
# 下标值增长幅度可以为负数
# 为负数表明顺序是从右往左
# 规定:数值最后一个数字得下标时-1
In [44]:
# 分片负数下标
print(l[-1:-5])
# 上面显示得是为空,因为默认分片总是从左往右截取
# 即正常情况,分片左边得值一定小于右边得值
print(l)
print(l[-4:-1])
# 如果非要左边值大于右边值,则不增长参数需要用负数
# 此案例为一个 list 直接正反颠倒提供了一种思路
print(l[-2:-4:-1])
?
## 分片操作是生成一个新的 list
?
- 内置函数 id 负责显示一个变量或者一个数据得唯一编号
分片操作是生成一个新的 list?
- 内置函数 id 负责显示一个变量或者一个数据得唯一编号
In [47]:
# id 函数案例
a = 100
b = 200
print(id(a))
print(id(b))
?
?
c = a
print(id(c))
?
# 如果 a 和 c 指向同一份数据,则a 得值改变同样 c 得值也会随之改变
# 但是,显示得结果并非如此,为什么??
print(a)
print(c)
In [49]:
# 通过 id 可以直接判断出分片是从新生成了一份数据还是使用得同一数据
l = [1,23,34,46,5,6,78,8]
ll = l[:]
lll = ll
# 如果两个 id 值一样,则表明分片生产得列表是使用得同一地址同一份数据
# 否则,分片生产得列表是重新生成一份数据,即一个新的列表,然后把数值拷贝新的列表中
print(id(l))
print(id(ll))
print(id(lll))
In [50]:
# 通过 id 知道,ll 和lll 是同一份数据,验证代码如下
l[1] = 200
print(l)
print(ll)
?
ll[1] = 200
print(ll)
print(lll)
In [ ]:
以上是关于函数作用域和列表常用操作的主要内容,如果未能解决你的问题,请参考以下文章