python笔记-0428

共享内存

a = 1
b = a
print(a == b)  #True
print(a is b)  #True
print(id(a))   #8791381152576
print(id(b))   #8791381152576

直接赋值、浅拷贝和深度拷贝解析
直接赋值:其实就是对象的引用(别名)。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

import copy

a = [1, 2, 3, 4, ['a', 'b']]  # 原始对象

b = a                  # 赋值,传对象的引用
c = copy.copy(a)       # 对象拷贝,浅拷贝
d = copy.deepcopy(a)   # 对象拷贝,深拷贝

a.append(5)            # 修改对象a
a[4].append('c')       # 修改对象a中的['a', 'b']数组对象

print('a = ', a)       #a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
print('b = ', b)       #b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
print('c = ', c)       #c =  [1, 2, 3, 4, ['a', 'b', 'c']]
print('d = ', d)       #d =  [1, 2, 3, 4, ['a', 'b']]


浅拷贝
拷贝之后元素一样,内存地址不同

a = [1,2,3]
b = a.copy()
print(a == b) #True
print(id(a))  #30433864
print(id(b))  #30433928

可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict,set则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
传不可变对象实例

def jisuan(a,b):
    a = 10
    c = a + b
    return c
x = 5
y = 6
z = jisuan(x,y)
print(z) #16

传可变对象实例

x = [1,2,3]
y = [4,5,6]
def modify(a,b):
    b = [5,6,7]
    b.append(4)
modify(x,y)
print(x) #[1, 2, 3]
print(y) #[4, 5, 6]

可变类型作为默认参数时,会造成歧义

def hanshu(a = []): #不建议使用可变类型作为默认参数,因为会造成歧义
    a.append("h")
    print(a)

hanshu() #['h']       # 默认调用a的地址
hanshu() #['h', 'h']  # 默认调用a的地址

全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

a = [1,2,3] #全局变量
def hanshu():
    x = 1 #局部变量
    print(a) #[1, 2, 3]
hanshu()
print(x) # x是局部变量,只能在函数内部访问

locals(),查看局部变量
globals(),查看全局变量

def hanshu(a,b):
    i = 1
    j = 2
    print(locals()) #{'a': 3, 'b': 4, 'i': 1, 'j': 2}

x = 3
y = 4
hanshu(x,y)
print(globals()) #{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001D66320>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Python编程_从入门到实践/04.28.py', '__cached__': None, 'hanshu': <function hanshu at 0x0000000001CFC1E0>, 'x': 3, 'y': 4}

注意变量的赋值顺序,和作用域

a = 1
b = 2
def hanshu():
    print(a) #1
    print(b) #2
    print(c) #NameError: name 'c' is not defined

hanshu()
c = 3

全局变量可以和局部变量重名:

a = 3
def hanshu():
    a += 5 #a = a + 5  # a没有被赋值
    print(a)
hanshu() #UnboundLocalError: local variable 'a' referenced before assignment
print(a) #3

如果全局变量是不可变数据类型,函数无法修改全局变量的值:

a = 1
def hanshu():
    a = 2 #局部变量,只作用于函数里面,无法改变函数外部的不可变数据
    print(a)
hanshu() #2
print(a) #1

如果全局变量是可变数据类型,函数可以修改全局变量的值:

a = [1,2,3,4]
def hanshu():
    a.append(5) #a地址不变,添加元素5,修改了列表a
hanshu()
print(a) #[1, 2, 3, 4, 5]

如果全局变量是可变数据类型,函数可以修改全局变量的值:

a = [1,2,3,4]
def hanshu():
    a = [5,6,7] #局部变量,重新赋值,地址更改,但与全局变量无关
hanshu()
print(a) #[1, 2, 3, 4, 5]

函数嵌套

def hanshu1():
    def hanshu2(x,y):
        z = x + y
        return  z
    a = 2
    b = 3
    return hanshu2(a, b)

print(hanshu1()) #5

global 关键字把局部变量变成全局变量:

def hanshu1():
    global a
    a = 1
hanshu1() #调用hanshu1()函数
print(a) #1

b = 3
def hanshu2():
    global b
    b += 4 # b = 3 + 4
print(b) #3
hanshu2() #调用hanshu2()
print(b) #7

nonlocal 关键字可以修改函数的外层局部变量

b = 3
def outer():
    a = 1
    b = 4
    def inner():
        nonlocal a
        nonlocal b
        a = 2
        b = 5
    print(a) #1
    print(b) #4
    inner()  #调用inner()函数
    print(a) #2
    print(b) #5

outer()
print(b) #3

变量作用域
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内置作用域(内置函数所在模块的范围)
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
用一个函数说明变量作用域的访问顺序:

a = 1
b = 4
c = 6
def outer():
    a = 2
    b = 5
    def inner():
        a = 3
        print("a =",a)       #a = 3 局部作用域
        print("b =",b)       #b = 5 嵌套作用域
        print("c =",c)       #c = 6 全局作用域
        print(max,__name__)  #<built-in function max> __main__  #內建作用域
    inner()
outer()

匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

a = lambda x,y:2 * x + y #这是一个匿名函数
b = a(1,2)
print(b) #4

a = lambda x,y,z:x*y*z
b = a(1,2,3)
print(b) #6

內建函数:

abs()返回绝对值:

print(abs(18))  #18
print(abs(-18)) #18

max()方法返回给定参数的最大值
max()方法的语法
max( x, y, z, … )

a = [1,3,5,-6,-2,-9]
print(max(a)) #5

min() 方法返回给定参数的最小值

a = [1,3,5,-6,-2,-9]
print(min(a)) #-9

求绝对值最大的数

a = [-7,-2,-3,4,5,6]
b = max(a,key=abs)
print(b) #-7

求相反数最大的数:

方法一:

def hanshu(a):
    return - 1 * a
a = [10,20,30,-50,60]
b = max(a,key = hanshu)
print(b) #-50

方法二

a = [10,20,30,-50,60]
b = max(a,key= lambda a:-1*a)
print(b) #-50

按绝对值大小排序

a = [2,-3,1,-5,4]
a.sort(key=abs)
print(a)

map(function, iterable, …)
根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

把元组x = (1,2,3),每个元素都乘以它本身,并返回一个列表
方法一

def hanshu(a):
    return a*a

x = (1,2,3)
y = map(hanshu,x)
print(y) #<map object at 0x0000000001EF9630>
for i in y:
    print(i,end = " ") #1 4 9

方法二

def hanshu(a):
    return a*a
x = (1,2,3)
y = map(lambda e:e*e,x)
print(y) #<map object at 0x0000000002959630>
for i in y:
    print(i,end = " ") #1 4 9

filter(function, iterable)
用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

把列表a = [1,2,3,4,5,6,7,8,9]中,所有能被3整数的数提出来

方法一

def shaixuan(a):
    if a % 3 == 0:
        return a

a = [1,2,3,4,5,6,7,8,9]
b = list(filter(shaixuan,a))
print(b) #[3, 6, 9]

方法二

def shaixuan(a):
    if a % 3 == 0:
        return a

a = [1,2,3,4,5,6,7,8,9]
b = list(filter(lambda x:x % 3 == 0,a))  #x % 3 == 0为True时,返回x
print(b) #[3, 6, 9]

zip([iterable, …])
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
我们可以使用 list() 转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

a = [1,2,3]
b = ["a","b","c","d"]
c = zip(a,b) # 返回一个对象
print(c) #<zip object at 0x00000000039E4208>
print(list(zip(a,b))) # list() 转换为列表,[(1, 'a'), (2, 'b'), (3, 'c')]
e,f = zip(*c) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
print(e) #(1, 2, 3)
print(f) #('a', 'b', 'c')

转换成指定格式:
方法一:

a = ("a","b")
b = ("c","d")
c = zip(a,b)
def dict(x):
    return {x[0]:x[1]}
list = []
for i in c:
    list.append(dict(i))
print(list)

方法二:

a = ("a","b")
b = ("c","d")
x = list(map(lambda x:{x[0]:x[1]},zip(a,b)))
print(x)


b = lambda x,y:x if x>y else y
print(b(2,3)) #3

用max()查找字典中的最大值
方法一:

a = {"a":1,"b":2,"c":3}

def zuidazhi(x):
    return a[x]

b = max(a,key=zuidazhi)
print(b) #c

方法二:

a = {"a":1,"b":2,"c":3}
b = max(a,key = lambda k:a[k])
print(b) #c

查找年龄最大的,给列表按年龄大小排序

a=[{"name":"张三",'age':18},
   {"name":"李四",'age':28},
   {"name":"王五",'age':48},
   {"name":"小明",'age': 8},
   ]
def hanshu(a):
    return a["age"]
b = max(a,key=lambda a:a["age"]) #查找
print(b) #{'name': '王五', 'age': 48}
a.sort(key=lambda a:a["age"]) #排序
print(a) #[{'name': '小明', 'age': 8}, {'name': '张三', 'age': 18}, {'name': '李四', 'age': 28}, {'name': '王五', 'age': 48}]

注意变量的查找顺序:

def outer():
    x = 3
    def inner(n):
        return x ** n
    return inner
a = outer()
print(a(3)) #27


def hs(x,y):
    return x + y
b = hs
print(b(1,2)) #3

闭包函数

def inter():
    x = 3
    z = lambda n:n*x
    return z
x = 9
b = inter()
print(b(2)) #6


def hanshu():
    list = []
    for i in range(4):
        list.append(lambda a:a * i)
    return list
a = hanshu()
print(a[0](2)) #6
print(a[1](2)) #6
print(a[2](2)) #6
print(a[3](2)) #6


i = 5
a = lambda x:x*i
i = 6
b = lambda x:x*i
print(a(2)) #12
print(b(2)) #12

猜你喜欢

转载自blog.csdn.net/jiameheng/article/details/89644299