python学习笔记4

python学习笔记4

变量作用域

  • 变量由作用范围限制
  • 分类: 按照作用域分类
    • 全局(global):在函数外部定义
    • 局部(local) :在函数内部定义
  • 变量的作用范围:
    • 全局变量:在整个全局范围都有效
    • 全局变量在局部可以使用
    • 局部变量在局部范围可以使用
    • 局部变量在全局范围无法使用
  • LEGB原则
    • L(local)局部作用域
    • E(Enclosing function locale)外部嵌套函数作用域
    • G(Global module)函数定义所在模块作用域
    • B(Building)python内置模块作用域

提升局部变量为全局变量

  • 使用global
  • 案例如下
def fun():
    global b1
    b1 = 100
    print(b1)
    print("I am fun")
    b2 = 99
    print(b2)

    
    
fun()
print(b1)
100
I am fun
99
100

globals, locals函数

  • 可以通过globals和locals显示出局部变量和全局变量
  • 参看以下案例
# globals 和 locals
# globals 和 locals叫做内建函数
a = 1
b = 2

def fun(c,d):
    e = 111
    print("Locals={0}".format(locals()))
    print("Globals={0}".format(globals()))
fun(100,200)
Locals={'c': 100, 'd': 200, 'e': 111}
Globals={'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n   # b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\nfun(100,200)'], '_oh': {}, '_dh': ['E:\\python\\jupyter_program'], 'In': ['', 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n   # b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\nfun(100,200)'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x0000021438109668>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002143A859D30>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002143A859D30>, '_': '', '__': '', '___': '', '_i': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n   # b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_ii': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_iii': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_i1': 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', 'fun': <function fun at 0x000002143A9F8598>, '_i2': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \nprint(b1)\nfun()', '_i3': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_i4': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n    b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_i5': 'def fun():\n    b1 = 100\n    global b1\n    print(b1)\n    print("I am fun")\n   # b2 = 99\n    print(b2)\n    \n#print(b1)\nfun()', '_i6': '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\nfun(100,200)', 'a': 1, 'b': 2}

eval()函数

  • 把一个字符串当成一个表达式来执行,返回表达式执行后的结果
  • 语法
    eval(string_code, globals=None,locals=None)

exec()函数

  • 功能类似,不返回结果
  • 语法
    exec(string_code, globals=None,locals=None)
x = 100
y = 200
# z = x + y
z1 = x + y
z2 = eval("x+y")
print(z2)
print(z1)
300
300
x = 100
y = 200
# z = x + y
z1 = x + y
z2 = exec("print('x+y:' , x+y)")
print(z1)
print(z2)

x+y: 300
300
None

递归函数

  • 函数直接或者间接调用自身
  • 优点:简洁,容易理解
  • 缺点:对递归深度有限制,消耗资源大
  • python中递归深度有限制,超过限制报错
  • 在写递归程序的时候,一定注意结束条件
# 递归调用深度限制代码
x = 0
def fun():
    global x
    x +=1
    print(x)
    #函数自己调用自己
    fun()
# 调用函数
fun()
---------------------------------------------------------------------------

RecursionError                            Traceback (most recent call last)

<ipython-input-11-7586de2e387c> in <module>
      8     fun()
      9 # 调用函数
---> 10 fun()


<ipython-input-11-7586de2e387c> in fun()
      6     print(x)
      7     #函数自己调用自己
----> 8     fun()
      9 # 调用函数
     10 fun()


... last 1 frames repeated, from the frame below ...


<ipython-input-11-7586de2e387c> in fun()
      6     print(x)
      7     #函数自己调用自己
----> 8     fun()
      9 # 调用函数
     10 fun()


RecursionError: maximum recursion depth exceeded while calling a Python object
 # 斐波那契数列
def fib(n):
    if n == 1:
        return 1
    if n == 2:
        return 1
    return fib(n-1) + fib(n-2)

fib(5)

    
5

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

  • list
  • set
  • dict
  • tuple

list (列表)

  • 一组有顺序的数据的组合
  • 创建列表
    • 空列表
#创建空列表
l1 = []
print(type(l1))

#创建带值的列表
l2 = [100]

#创建列表,带多个值
l3 = [1,2,3,4,5,6,7,8,9]

# 使用list
l4 = list()
<class 'list'>

列表常用操作

  • 访问
    • 使用下标操作(索引)
    • 下标从0开始
  • 切片操作
    • 对列表进行任意一段截取
    • l[:]
# 下标访问列表
l = [1,2,3,4,5,6,7]

print(l[2])
3
#分片操作,包含左,不包含右
print(l[1:4])

# 下标值可以为空,如果不写,左边默认为零,右边下标最大数加一,即表示截取到最后一个数据
print(l[:])
print(l[:4])
print(l[2:])

# 分片可以控制增长幅度,即在后面在增加一个:然后设置步长,例如:
print(l[1:6:2])


# 下标可以超出范围,超出后不再考虑多余下标内容
print(l[2:10])


# 下标值增长幅度可以为负数
# 为负数,表明顺序是从右向左
# 规定: 数组最后一个数字的下标识-1


#分片之负数下标,左边的值一定要大于右边的值 (绝对值)
print(l[-4:-1])

# 如果左边的值一定要小于于右边的值,则步长要为-1
print(l[-1:-4:-1])
[2, 3, 4]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4]
[3, 4, 5, 6, 7]
[2, 4, 6]
[3, 4, 5, 6, 7]
[4, 5, 6]
[7, 6, 5]

分片操作是生成一个新的list

  • 内置函数id:负责显示一个变量或者数据的唯一确定编号
# id函数举例
a = 100
b = 200

print(id(a))
print(id(b))

c = a
print(id(c))
a = 101
print(a)
print(c)






140730893836192
140730893839392
140730893836192
101
100
# 通过id()可以直接判断出分片是生成了一份新数据还是使用的同一份数据,id值一样的话,则为同一份数据
l = [1,2,3,4,5,6,7,8,9]
ll = l[:]
lll = ll
print(id(l))
print(id(ll))
print(id(lll))

# 通过id知道,ll和lll同一份数据,验证代码如下
l[1] = 100
print(l)
print(ll)

ll[1] = 100
print(ll)
print(lll)

2293562915656
2293563151112
2293563151112
[1, 100, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 100, 3, 4, 5, 6, 7, 8, 9]
[1, 100, 3, 4, 5, 6, 7, 8, 9]

汉诺塔问题

  • 方法
    • n = 1: 1步
    • n = 2: 3步
    • n = 3: 递归实现
def hano(n,a,b,c):
    '''
    n代表有几个盘子
    a代表第一个盘子
    b代表第二个盘子
    c代表第三个盘子
    '''
    if n == 1:
        print(a,"-->",c)
        return None
    if n == 2:
        print(a,"-->",b)
        print(a,"-->",c)
        print(b,"-->",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"
    
n = 3
hano(n,a,b,c)
  
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C

list(列表)

  • del: 删除命令
# del 删除列表中的一个元素,在原位置删除
a = [1,2,3,4,5]
print(id(a))
del a[2]
print(id(a))
print (a)
1980825909768
1980825909768
[1, 2, 4, 5]
# del 一个变量后不能继续使用此变量

列表相加

  • 使用加号连接两个列表
# 使用加号连接列表
a = [1,2,3,4,5,6]
b = [7,8,9,0]
d = ['a','b']
c = a + b + d
print(c)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'a', 'b']
# 使用乘号操作列表
# 列表直接和一个整数相乘
# 相当于把n个列表连接在一起
a = [1,2,3,4,5,6]
b = a * 3
print(b)
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]

# 成员资格运算
# 就是判断一元素是否在list里面
a = [1,2,3,4,5,6]
b = 8
d = 1

c= b in a
print(c)
print(d in a)








False
True
# not in
a = [1,2,3,4,5,6]
b = 9
print(b not in a)





True

列表的遍历

  • for
  • while
# for i in list
a = [1,2,3,4,5,6]
for i in a:
    print (i)


    





1
2
3
4
5
6
b = ["I Love Lilingling"]
for i in b:
    print(i)
I Love Lilingling
# while访问list
# 一般不用while访问list
a = [1,2,3,4,4,5,6,7,7]
length = len(a)
#index表示的是list的下标
index = 0
while index < length:
    print(a[index])
    index += 1






1
2
3
4
4
5
6
7
7
# 双层列表循环

# a 为嵌套列表,或者叫双层列表

a = [["one",1],["two",2],["three",3]]
for k,v in a:
    
    print(k,"--",v)



one -- 1
two -- 2
three -- 3


# 双层列表循环变异

# a 为嵌套列表,或者叫双层列表

a = [["one",1,"sdds"],["two",2],["three",3,4,5,6]]
for k,v in a:
    print(k,"--",v)


---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-39-5be6077ce179> in <module>
      6 
      7 a = [["one",1,"sdds"],["two",2],["three",3,4,5,6]]
----> 8 for k,v in a:
      9 
     10     print(k,"--",v)


ValueError: too many values to unpack (expected 2)
# 双层列表循环变异

# a 为嵌套列表,或者叫双层列表

a = [["one",1,"sdds"],["two",2,"dsdds"],["three",3,"assaas"]]
for k,v,w in a:
    print(k,"--",v,"--",w)

    
    
    
    
    
one -- 1 -- sdds
two -- 2 -- dsdds
three -- 3 -- assaas

列表内涵: list content

  • 通过简单方法创建列表
# for 创建
a = ['a','b','c']
#用list a创建一个 list b
#下面代码的含义是,对于所有a中的元素,逐个放入新列表b中
b = [i for i in a]
print(b)




['a', 'b', 'c']
# 对a中所有的元素乘以10,生成一个新的list
a = [1,2,3,4,5]
#用list a创建一个 list b
#下面代码的含义是,对于所有a中的元素,逐个放入新列表b中
b = [i*10 for i in a]
print(b)

[10, 20, 30, 40, 50]
# 还可以过滤原来list中的内容并放入新列表中
# 比如原有列表a, 需要把所有a中的偶数生成新的列表b
a = [x for x in range(1,35)]
b = [m for m in a if m % 2 ==0]
print(b)




[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34]
# 列表生成式可以嵌套
# 由两个列表a,b
a = [i for i in range (1,4)]
print(a)

b = [i for i in range (100,400) if i % 100 == 0]
print(b)


c = [m+n for m in a for n in b]
print(c)

# 和上面等价
for m in a:
    for n in b:
        print(m+n,end = " ")
print()


# 嵌套的列表生成式也可以用条件表达式
c = [m+n for m in a for n in b if m+n <250]
print(c)
[1, 2, 3]
[100, 200, 300]
[101, 201, 301, 102, 202, 302, 103, 203, 303]
101 201 301 102 202 302 103 203 303 
[101, 201, 102, 202, 103, 203]

关于列表的常用函数

# len: 求列表的长度
a = [x for x in range(1,100)]
print(len(a))

# max/min求列表中最大/小值
print(max(a))
print(min(a))
99
99
1
# list: 将其它格式数据转换成list
a = [1,2,3]
print(list(a))







[1, 2, 3]
s = "I Love Lilingling"
print(list(s))
['I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 'i', 'l', 'i', 'n', 'g', 'l', 'i', 'n', 'g']
# 把range产生的内容转换成list
print(list(range(1,11)))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

传值和传地址的区别

  • 对于简单的数值,采用传值的操作,即在函数内对参数的操作不影响外部变量
  • 对于复杂的变量,采用传地址操作,此时函数内的参数和外面变量是同一份内容,任何地方对此内容的更改都影响另外的变量或者参数的使用

关于列表的函数

l = ['a',"I Love Lilingling",23,45,675]
#追加:在队尾插入数据 append
print(l)
l.append(100)
print(l)


#指定位置插入 insert(index,date)
l.insert(3,"dhsudh")
print(l)


# 删除
# del删除
# pop,从队尾拿出一个元素,即把最后一个元素取出来
print(l)
last_ele = l.pop()
print(last_ele)
print(l)

# remove:在列表中删除指定的元素,如果指定的值没有在list中,则会报错
# 判断语句:
# if x in list
# list.remove(x)
print(l)
print(id(l))
l.remove(23)
print(l)
print(id(l))


# clear 清空,列表没变,只是把数据清空了
print(l,"--",id(l))
l.clear()
print(l,"--",id(l))

# 如果不需要地址保持不变,则清空列表可以选择以下方式
# a = list()
# a = []

['a', 'I Love Lilingling', 23, 45, 675]
['a', 'I Love Lilingling', 23, 45, 675, 100]
['a', 'I Love Lilingling', 23, 'dhsudh', 45, 675, 100]
['a', 'I Love Lilingling', 23, 'dhsudh', 45, 675, 100]
100
['a', 'I Love Lilingling', 23, 'dhsudh', 45, 675]
['a', 'I Love Lilingling', 23, 'dhsudh', 45, 675]
2447470924872
['a', 'I Love Lilingling', 'dhsudh', 45, 675]
2447470924872
['a', 'I Love Lilingling', 'dhsudh', 45, 675] -- 2447470924872
[] -- 2447470924872
# reverse:翻转

# 原地翻转
a = [1,2,3,4,5,6,7]
print(a)
print(id(a))

a.reverse()
print(a)
print(id(a))

[1, 2, 3, 4, 5, 6, 7]
2447470942216
[7, 6, 5, 4, 3, 2, 1]
2447470942216
# extend:扩展列表,两个列表,把一个直接拼接到后一个上

a = [1,2,3,4]
b = [5,6,7,8]
print(a)
print(id(a)
     )
a.extend(b)
print(a)
print(id(a))
# count 查找列表中指定值或者元素的个数
print(a)
a_len = a.count(8)
print(a_len)

a.append(8)
a.insert(2,8)
print(a)
a_len = a.count(8)
print(a_len)

[1, 2, 3, 4, 5, 6, 7, 8]
1
[1, 2, 8, 3, 4, 5, 6, 7, 8, 8]
3
# copy :浅拷贝
#列表类型变量赋值示例
a = [1,2,3,4,5,666]
print(a)

#list类型,直接赋值,是传址操作,对b做修改,也会修改a
b = a
b[3] = 777
print(a)
print(id(a))
print(b)
print(id(b))

# 拷贝:只传值,不传址,采用copy函数,参看以下案例
b = a.copy()
print(a,"a的地址是",id(a))
print(b,"b的地址是",id(b))
[1, 2, 3, 4, 5, 666]
[1, 2, 3, 777, 5, 666]
2447470108808
[1, 2, 3, 777, 5, 666]
2447470108808
[1, 2, 3, 777, 5, 666] a的地址是 2447470108808
[1, 2, 3, 777, 5, 666] b的地址是 2447471307848
# 浅拷贝和深拷贝的区别
# 浅拷贝,只拷贝了一层内容
a = [1,2,3,[1,2,3]]
b = a.copy()
print(a)
print(b)
print(id(a[3]))
print(id(b[3]))
a[3][2] = 666
print(a)
print(b)


# 深拷贝,需要使用特定工具
[1, 2, 3, [1, 2, 3]]
[1, 2, 3, [1, 2, 3]]
2447471276616
2447471276616
[1, 2, 3, [1, 2, 666]]
[1, 2, 3, [1, 2, 666]]

元祖 tuple

  • 可以看成一个不可操作的列表

元祖创建

# 创建空元祖
t = ()
print(type(t))

# 创建只有一个元素的元祖
t = (1,)
print(type(t))
print(t)

t = 1,
print(type(t))
print(t)

t = 1,2,3,4,5
print(type(t))
print(t)

t = (1,2,3,4,5)
print(type(t))
print(t)

# 使用其他结构创建
l = [1,2,3,4,5]
l = tuple(l)
print(type(t))
print(t)
<class 'tuple'>
<class 'tuple'>
(1,)
<class 'tuple'>
(1,)
<class 'tuple'>
(1, 2, 3, 4, 5)
<class 'tuple'>
(1, 2, 3, 4, 5)
<class 'tuple'>
(1, 2, 3, 4, 5)

元祖的特性

  • 是序列表,有序
  • 元祖数据可以任意访问,不能修改,不能修改,不能修改!
  • 元祖元素可以是任意类型
  • 总之,list所有特性,除了可修改之外,元祖都具有
# 索引操作
t = (1,2,3,4,5)
print(t[2])
3
# 超标错误
print(t[10])
---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

<ipython-input-40-a7f4fce0da2c> in <module>
      1 # 超标错误
----> 2 print(t[10])


IndexError: tuple index out of range
t = (1,2,3,4,5,6,7,8,9)
t1 = t[1::2]
print(id(t))
print(id(t1))
print(t1)


# 切片可以超标
t2 = t[2:100]
print(t2)
2447470508816
2447471340584
(2, 4, 6, 8)
(3, 4, 5, 6, 7, 8, 9)
# 序列相加
t1 = (1,2,3)
t2 = (5,6,7)

# 传址操做
print(t1)
print(id(t1))
t1 = t1 + t2
print(t1)
print(id(t1))


# tuple的不可修改,指的是内容的不可修改
# 修改会报错
(1, 2, 3)
2447469710504
(1, 2, 3, 5, 6, 7)
2447469449032
# 元祖相乘
t = (1,2,3,4)
t = t * 3
print(t)
(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4)
# 成员检测
t = (1,2,3,4)
if 2 in t:
    print("yes")
else:
    print("no")


yes
# 元祖遍历
# 1. 单层元祖遍历
t = (1,2,3,4,5,"dsdsds",'d')
for i in t:
    print(i,end="")
    
12345dsdsdsd
# 2. 双层元祖遍历
t = ((1,2,3),(4,5,6),("I","Love","Lilingling"))
for i in t:
    print(i)
    
for k,m,n in t:
    print(k,m,n)

(1, 2, 3)
(4, 5, 6)
('I', 'Love', 'Lilingling')
1 2 3
4 5 6
I Love Lilingling
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值