python知识点杂谈

zip

for循环中对多个可迭代对象进行同时访问

A,B=[],[]
for a,b in zip(A,B):
	print(a,b)

当可迭代对象长度不等时,zip会以最短长度为标准;如果希望以最长长度为标准,使用itertools.zip_longest(),自动补齐None。

引用,浅拷贝&深拷贝,视图

引用

在Python中,使用 = 赋值时,‌本质上是创建了一个新的引用指向同一个对象‌,而非创建新对象。这种机制可以理解为“别名”(aliasing)

  • 可变对象(如列表、字典、集合)
    修改对象内容时,所有引用都会变化
  • 不可变对象(如整数、字符串、元组)
    修改时实际是创建新对象,原引用不受影响

浅复制

定义‌:复制对象本身,但不会递归复制其内部的嵌套对象(如列表中的子列表、字典中的嵌套字典等)。

‌特点‌:
新对象和原对象是独立的,但内部的嵌套对象仍共享同一引用。
简单来说就是只有第一维的元素是独立的,内部嵌套的更高维度的元素仍然共享。

a = [1, [2, 3]]
b = a.copy()  # 浅复制

深复制

‌定义‌:递归复制对象及其所有嵌套对象,生成完全独立的副本。

‌特点‌:
新对象与原对象及其内部嵌套对象均无任何引用关联。

import copy
a = [1, [2, 3]]
b = copy.deepcopy(a)  # 深复制

不可变对象如整数、字符串):浅复制和深复制效果相同(因不可变性)

视图

是numpy中的概念
特点:

  • 是原数组数据的另一种查看方式,与原数组共享同一块内存
  • 修改视图会影响原数组
  • 创建方式:切片操作、reshape()、transpose()等

Iterator,迭代器

任何继承自Iterator的类,比如常见的list、dict,都可以通过next()依次访问元素,也可以用for循环访问

使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)

列表表达式

for前面的部分是一个表达式,它必须根据x计算出一个结果。
因此,表达式:x if x % 2 == 0无法根据x计算出结果

>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

上述for前面的表达式x if x % 2 == 0 else -x才能根据x计算出确定的结果。

可见,在一个列表生成式中,for前面的if … else是表达式
而for后面的if是过滤条件,不能带else

generator

generator的思想和滚动数组类似:
滚动数组:在递推中保存递推中几个必要的变量,不保存之前的递推数据来节省内存
generator:生成器函数会暂停执行并保存当前状态,下次调用时从停止处继续(惰性计算,需要时生成数据,不保存多余历史数据)、

访问generator,可以调用next(),或者使用for循环,generator也是可迭代对象

要创建一个generator,有很多种方法。

第一种方法

很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

 >>> L = [x * x for x in range(10)]
 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
 >>> g = (x * x for x in range(10))
 <generator object <genexpr> at 0x1022ef630>

另一种方法:

如果一个函数定义中包含yield关键字,那么这个函数是一个generator函数

请务必注意:调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。

装饰器

假设我们要增强函数的功能,比如在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)

本质上,decorator就是一个返回函数的高阶函数。

所以,我们要定义一个能打印日志的decorator,可以定义如下:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

观察上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:

@log
def now():
    print('2024-6-1')

调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:

>>> now()
call now():
2024-6-1

面向对象编程

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__

变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的。

self.x=x代表绑定实例的属性,直接声明或定义则是类属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值