Python_学习历程(函数的作用域-内置数据结构)

Python_学习笔记之“函数的作用域-内置数据结构”

    • 函数的作用域
    • 递归函数
      • 递归之斐波那契数列
      • 递归之汉诺塔
    • 内置数据结构(变量类型)
      • list (列表)
      • set(集合)
      • dict(字典)
      • tuple(元组)

函数的作用域

  • 变量由作用范围限制

    • 分类

      • 全局变量(global):在函数外部定义
      • 局部变量:在函数内部定义
    • 变量的作用范围:

      • 全局变量:在整个全局范围都有效
      • 函数内部可以访问全局变量
      • 局部变量仅限于局部,无法在全局使用
    • LEGB原则:

      • L (Local)局部作用域
      • E (Enclosing function locale)外部嵌套函数作用域
      • G (Global module)函数定义所在模块作用域
      • B (Buildin)python内置模块的作用域
  • globals 函数和 locals 函数(内建函数)

    • 可以通过globals 和 locals 显示出局部变量和全局变量
  • eval()函数

    • 将一个字符串当成一个表达式来执行,返回表达式执行后的结果
    • 语法:
	eval(string_code, globals=Nonelocals=None
  • 示例:
x = 10
y = 20
# 执行x+y 
# z = x + y
z1 = x + y
z2 = eval"x+y"print(z1)
print(z2)
# result:
30
30
  • exec()函数
    • 功能与eval()函数结果一致,但没有返回值
    • 示例:
x = 10
y = 20
# 执行x+y
# z = x + y
z1 = x + y
z2 = exec"x+y"print(z1)
print(z2)
# result:
30
None

递归函数

  • 函数直接或者间接调用自身

  • 优点:简洁,易理解

  • 缺点:对递归的深度有限制,消耗资源大

  • python对递归深度有限制,超过限制会报错

  • 在写递归程序的时候,一定要注意边界条件

递归之斐波那契数列

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子
而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推
的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)

# n表示求第n个数字的斐波那契数列的值
def fib(n):
	if n == 1return 1
	if n == 2return 1
# 思考为什么后面return能够正确执行,而不用else语句
	return fib(n-1) + fib(n-2)
	
print(fib(3))
print(fib(10))
# result:
2
55

递归之汉诺塔

汉诺塔规则:
1.每次只能移动一个盘子
2.任何一次移动,三个塔的状态必须是小盘子在上,大盘子在下

def hano(n, a, b, c):
	'''
	汉诺塔的递归实现:
	n:代表盘子的个数
	a:代表第一个塔(初始)
	b:代表第二个塔(过渡)
	c:代表第三个塔(目标塔)
	'''
	if n == 1:
		print(a, "-->", c)
		return None

	# 把n-1个盘子,从a塔借助c塔,移动到b塔上
	hano(n - 1, a, c, b)
	print(a, "-->", c)
	# 把n-1个盘子,从b塔借助a塔,移动到c塔上
	hano(n - 1, b, a, c)

a = "A"
b = "B"
c = "C"

hano(3, a, b, c)
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C

内置数据结构(变量类型)

list (列表)

  • 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

  • Python有6个序列的内置类型,但最常见的是列表和元组。

  • 序列都可以进行的操作包括索引,切片,加,乘,检查成员

  • 列表的数据项不需要具有相同的类型

  • 创建列表逗号分隔的不同的数据项使用方括号括起来即可

  • 创建列表:

# 创建空列表
l1 = []
# type是内置函数,负责打印出变量的类型
print(type(l1))

# 创建带值的列表
l2 = [100]
print(type(l2))
print(l2)

# 创建一个带多值的列表
l3 = [2,3,4,5,6]
print(type(l3))
print(l3)

# 使用 list() 函数
l4 = list()
print(type(l4))
print(l4)
  • 列表操作
  • 访问使用下标操作(索引)
  • 列表的下标从 0 开始
# 下标访问列表
lst = [9,6,3,2,1]
print(l[2])
3
  • 切片操作(通俗来讲就是对列表任意一段的截取)
  • 用法: list[start: end: step]
#切片操作
#注意截取的范围,包含左边的下标值,不包含右边的下标值
lst = [9,6,3,2,1]
print(lst[1:3])
print(lst[:])
print(lst[:4])
print(lst[2:])
# 切片可以控制增长的幅度(步长)
# 下标可以超出范围,但超出后不考虑余下内容
# 最后一个数字的下标为 -1

# 切片默认从左往右
# 正常情况下,切片左边的值一定小于右边的值

# 如果切片左边值大于右边值,步长参数需要使用负数
print("1-",lst[-4:-2])
print("2-",lst[-2:-4])
# result:
[6, 3]
[9, 6, 3, 2, 1]
[9, 6, 3, 2]
[3, 2, 1]
1- [6, 3]
2- []
  • 切片操作生成一个新的 list
    • 可以使用内置函数id来验证
# 通过id判断出切片是新生成了一个list还是同一个list
lst = [1,5,2,4,7,89,123]
lst_1 = lst[:]
lst_2 = lst_1

print(id(lst))
print(id(lst_1))
print(id(lst_2))
# result:
2091311194632
2091311194696
2091311194696
  • del 删除命令
# del 删除
lst = [1,2,3,4,5,6]
del lst[2]
print(lst)
# result:
[1,2,4,5,6]
  • 此示例说明 del 为原地操作,内存地址不变
lst = [1,2,3,4,5,6]
print(lst)
print(id(lst))
del lst[2]
print(lst)
print(id(lst))
# result:
[1, 2, 3, 4, 5, 6]
2429626573320
[1, 2, 4, 5, 6]
2429626573320
  • 使用加号链接两个列表
lst_a = [1,2,3]
lst_b = [4,5,6]
lst_c = ["a","b","c"]
lst = lst_a + lst_b + lst_c
print(lst)
# result:
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c']
  • 使用乘号操作列表
# 列表直接跟一个整数相乘
# 相当于把n个列表接在一起
lst = [1,2,3]
lst_a = lst * 3
print(lst)
print(lst_a)
# result:
[1, 2, 3]
[1, 2, 3, 1, 2, 3, 1, 2, 3]
  • 成员资格判断
# 即判断一个元素是否在list中
lst = [1,2,3]
a = 3
# 返回的是一个布尔值
b = a in lst
print(b)
# result:
True
  • 列表的遍历
# for * in list 
# in 后的变量应是可迭代对象
lst = [1,2,3,4,5]
for i in lst:
	print(i)
# result:
1
2
3
4
5
  • list content
# 此种用法可以过滤原来列表并放入新列表
a = [1,2,3,4,5]
b =[i*10 for i in a]
print(b)

# 将列表lst中的偶数放入lst_a
lst = [i for i in range(1,11)]
lst_a =[j for j in lst if j % 2 == 0]
print(lst_a)

# 列表生成式可以嵌套
# 生成两个列表lst_1和lst_2
lst_1 = [i for i in range(1,4)]
print(lst_1)
lst_2 = [j for j in range(1,400) if j % 100 == 0]
print(lst_2)
# 其实相当于两个for循环嵌套,但示例生成的是列表
lst_3 = [m+n for m in lst_1 for n in lst_2]
print(lst_3)

# 上下大致等价
for m in lst_a:
	for n in lst_b:
		print(m+n,end=" ")
print()
# result:
[10, 20, 30, 40, 50]
[2, 4, 6, 8, 10]
[1, 2, 3]
[100, 200, 300]
[101, 201, 301, 102, 202, 302, 103, 203, 303]
101 201 301 102 202 302 103 203 303 
  • 列表常用的函数和方法
# len() :求列表的长度
lst = [i for i in range(1,50)]
print(len(lst))

# max() :求列表中元素的最大值
# min() :求列表中元素的最小值
print (max(lst))
print (min(lst))

# list() :将其他格式的数据转换为lsit类型
str = "ni hao ya ,jing ke ai!"
lst = list(str)
print(lst)

# 把range()产生的内容转换为lsit
print(list(range(1,99)))
49
49
1
['n', 'i', ' ', 'h', 'a', 'o', ' ', 'y', 'a', ',', 'J', 'i', 'n', 'g', ' ', 'k', 'e', ' ', 'a', 'i', '!']
[1, 2, 3, 4]
  • append(data) 插入一个元素,在末尾追加
  • **extend( )**方法可以将另一个迭代对象的所有元素添加至该列表对象的尾部。通过extend()方法来增加列表元素不改变其内存首地址,属于原地操作。
  • insert(index, data) 指定位置插入,插入位置在index之前。
  • pop( ) 弹出最后一个元素(默认),返回弹出的元素,如果给定的索引超出了范围,则抛出异常 。
  • remove( ) 删除首次出现的指定元素,如果列表中不存在要删除的元素,则抛出异常(此操作为原地操作)
    -reverse( ) 原地翻转
  • count( ) 查找列表中指定值或元素的个数
  • copy( ) 浅拷贝
  • clear( ) 清空列表

set(集合)

  • 集合(set)是一个无序的不重复元素序列。

  • 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

  • 创建格式:

parame = {v1,v2,3,........}
#或者
set(v1,v2,v3,........)
#集合具有自动去重功能
#集合具有自动去重功能
basket = {'apple', 'orange', 'pear', 'orange', 'banana'}
print(basket)

#集合的成员判断
print('orange' in basket)
print('hello' in basket)

#集合间的运算
set_a = set('abcdefg')
set_b = set('efghij')
print(set_a)
print(set_a - set_b)    # 集合set_a中包含而集合set_b中不包含的元素
print(set_a | set_b)    # 集合set_a或set_b中包含的所有元素
print(set_a & set_b)    # 集合set_a和set_b中都包含了的元素
print(set_a ^ set_b)    # 不同时包含于set_a和set_b的元素
#result:
{'orange', 'pear', 'apple', 'banana'}
True
False
{'a', 'e', 'g', 'f', 'd', 'b', 'c'}
{'a', 'c', 'd', 'b'}
{'a', 'e', 'i', 'g', 'f', 'h', 'd', 'b', 'c', 'j'}
{'g', 'f', 'e'}
{'a', 'i', 'h', 'd', 'b', 'c', 'j'}
  • 集合推导式,类似于列表推导式
set_a = {i for i in 'abcdefg' if i not in 'efg'}
print(set_a)
#result:
{'c', 'a', 'b', 'd'}
  • 对于集合的一些基本操作
#向集合中添加元素
a = {'apple','orange'}
print(a)
a.add('jingkeai')
print(a)

#set.update()也可以向集合添加元素(参数可以是列表,元组,字典等)
a = {'apple','orange'}
a.update({'a','b','c'})
print(a)
a.update([1,2,3],['J','K','A'])
print(a)

#删除集合中的元素
a.remove(1)   #remove只能有一个参数(只能删除一个元素),如果元素不存在,则会报错
print(a)

a.discard(1) #此方法删除集合中的元素,如果元素不存在,不会报错。
print(a)

#随机删除集合中的一个元素
a.pop()
print(a)    #这里每次输出的结果都可能不一致,因为pop对集合中的元素是随机弹出的

#统计集合中元素的个数
print(len(a))

#清空集合
a.clear()
print(a)
{'orange', 'apple'}
{'orange', 'jingkeai', 'apple'}
{'orange', 'b', 'apple', 'a', 'c'}
{1, 2, 3, 'J', 'c', 'b', 'a', 'orange', 'A', 'apple', 'K'}
{2, 3, 'J', 'c', 'b', 'a', 'orange', 'A', 'apple', 'K'}
{2, 3, 'J', 'c', 'b', 'a', 'orange', 'A', 'apple', 'K'}
{3, 'J', 'c', 'b', 'a', 'orange', 'A', 'apple', 'K'}
9
set()

dict(字典)

  • 字典是另一种可变容器模型,且可存储任意类型对象。

  • 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中

  • 格式:d = {key1 : value1, key2 : value2 …}

  • 键必须是唯一的,值不必唯一

  • 值可以是任何数据类型,键必须是不可变的(如字符串、数字、元组)

  • 字典创建实例:

#字典创建
dict_a = {'xuhaoxuan':20,'lijingyi':'19','datouerzi':'???'}
dict_b = {'1':'a',(1):3}
for k,v in dict_a.items():
    print(k,'->',v)
for k,v in dict_b.items():
    print(k,'->',v)

#访问字典的值
print("dict_a['xuhaoxuan']",dict_a['xuhaoxuan'])
print("dict_b['1']",dict_b['1'])   #如果访问字典里没有的键,则会报错keyError

#修改字典的值
dict_a['lijingyi'] = 'shazhu'
print("dict_a['lijingyi']",dict_a['lijingyi'])

#删除字典的元素
del dict_a['xuhaoxuan']
print(dict_a)
#清空字典
dict_a.clear()
print(dict_a)
#删除字典
del dict_a

# 字典的内置函数和方法
a = {'name':'xuhaoxuan','age':20,'class':2}
print(str(a))
print(type(str(a)))  #输出字典,用可打印的字符串表示
print(len(a)) #统计字典中键的个数
xuhaoxuan -> 20
lijingyi -> 19
datouerzi -> ???
1 -> a
1 -> 3
dict_a['xuhaoxuan'] 20
dict_b['1'] a
dict_a['lijingyi'] shazhu
{'lijingyi': 'shazhu', 'datouerzi': '???'}
{}
{'name': 'xuhaoxuan', 'age': 20, 'class': 2}
<class 'str'>
3

tuple(元组)

  • Python 的元组与列表类似,不同之处在于元组的元素不能修改。

  • 元组使用小括号,列表使用方括号。

  • 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

# 创建空元组
tup1 = (1,2,3,4)
print(tup1)
tup2 = ('xuhaoxuan',20)
print(tup2)
# 创建元组也可以不用括号
tup3 = 'xuhaoxuan','xieiqngsong',20,19
print(tup3)

# 特别注意,当元组中只有一个元素时,必须在该元素后面加逗号,否则括号会被当做运算符
tup1 = (1)
print(type(tup1)) # 此时是整型数据
tup1 = (1,)
print(type(tup1)) # 此时是元组

# 元组可以通过索引访问元素
print(tup3[1])
print(tup3[2:4])  # 右边界同样不包含

# 元组的元素不能进行修改,但是可以进行连接
tup_a = tup3 + tup2
print(tup_a)  # 两个'xuhaoxuan'都被元组保存,说明元组的值是可以重复的

# 元组的值不能被删除,但可以直接删除整个元组
del tup_a

# 元组可迭代
# tuple()函数可以将列表转换为元组
#result:
(1, 2, 3, 4)
('xuhaoxuan', 20)
('xuhaoxuan', 'xieiqngsong', 20, 19)
<class 'int'>
<class 'tuple'>
xieiqngsong
(20, 19)
('xuhaoxuan', 'xieiqngsong', 20, 19, 'xuhaoxuan', 20)

你可能感兴趣的:(python学习笔记)