流畅的python笔记(二)数据结构

numpy 详解 numpy 详解numpy 的意义:一、矩阵的创建1.列表或元组创建2.np函数创建3.矩阵拼接二、ndarray 的常用属性、方法三、矩阵的操作(改维度、类型,索引,切片 )1.维度2.类型3.索引4.切片四、矩阵的运算1.四则运算和幂2.函数运算3.随机函数使用RandomState获得随机数生成器4.统计函数五、导入导出1.CSV2.tofile针对多维矩阵 numpy 的意义: -1.矩阵... 阅读详情

目录

一、内置序列类型概览

二、列表推导式和生成器表达式

列表推导式

生成器表达式

 三、元组

元组和记录

元组拆包

嵌套元组拆包

具名元组

元组作为不可变列表

四、切片

切片是左闭右开区间

多维切片和省略

修改切片就地改变原序列

五、对序列使用 + 和 *

六、序列的增量赋值 *= 与 +=

七、list.sort方法与内置函数sorted

八、用bisect模块管理已排序的序列

用bisect搜索

用bisect.insort插入新元素

九、替换列表的数据结构

数组

内存视图

NumPy和SciPy

双向队列和其它形式的队列

collections.deque

queue

multiprocessing

asyncio

heapq


一、内置序列类型概览

python的核心特点之一是对序列数据类型的支持。

按照序列能否存放不同类型对象分类:

容器序列

        list、tuple和collections.deque,这些是容器序列类型,同一个序列对象中可以存放不同类型的数据。

扁平序列

        str、bytes、bytearray、memoryview和array.array,这些是扁平序列类型,这种一个序列对象中只能容纳一种类型。

        容器序列存放的是其所包含的任意类型对象的引用,而扁平序列存放的就是值。可以类比为容器序列中存放的是指针(引用跟指针类似),通过指针来指向不同的元素。而扁平序列类型就像C语言中的数组,其本质是一段连续的内存空间。扁平序列其实更加紧凑,但是只能存放字符、字节和数值这种基础类型。

按照序列能否被修改分类:

可变序列

不可变序列

二、列表推导式和生成器表达式

一句话,列表推导式只用于构建列表,生成器表达式则可以用来创建任何类型的序列。

列表推导式

列表推导式只是构建列表的一种快捷方式。

直接看例子,

l = [x for x in "ABC"]
print(l)

可以看到列表推导式是用中括号围起来的,用for循环来生成列表,里边有两个x,第二个x就是for循环遍历的可迭代对象中的单个元素,第一个x不一定是直接x,也可以对x做各种操作,如下例子,上边列表中元素是字符,本例将字符变成unicode码。

l = [ord(x) for x in "ABC"]
print(l)

需要注意的是,再python3中,列表推导式是有自己的局部作用域的,即x是一个局部变量,改变x不会改变外边的变量。

        上边两个例子中可以认为列表推导式中都是只有一个变量x,其实可以有很多个变量,下边是一个有两个变量的例子。

colors = ['black', 'white']
sizes = ['S', 'M', 'L']

tshirts = [(color, size) for color in colors
                        for size in sizes]
print(tshirts)

 注意一下一个有意思的点:

 列表推导式一般用来生成列表,如果要生成其它类型的序列,就需要生成器表达式出场了。

生成器表达式

用法和列表推导式几乎一模一样,只不过把中括号换成了小括号。

symbols = "acbdf"
t = tuple(ord(symbol) for symbol in symbols)
print(t)

如果生成器表达式是函数调用中的唯一参数,那么生成器表达式的小括号可以去掉,直接放在函数调用的小括号里边即可。

        也可以用列表推导式来生成元组等类型,其过程是先生成一个列表,然后再将列表作为参数传递给元组类的某个构造函数。而用生成器表达式则是逐个地产出元素,而不是先建立一个完整的列表,显然生成器表达式能够更节省内存。

        还是上边那个两个变量的例子,如果要打印出所有的组合,用列表推导式需要在内存中建立一个二维序列,当这个序列很大时这是不可接受的。而用生成器表达式则是一次只生成一个元素。

colors = ['black', 'white']
sizes = ['S', 'M', 'L']

for tshirt in ('%s %s' % (c, s) for c in colors
                                for s in sizes):
    print(tshirt)

 

 三、元组

city , year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
for passport in sorted(traveler_ids):
    print('%s/%s' % passport)
for country, _ in traveler_ids:
    print(country)

元组和记录

不应当只把元组当作不可变的列表,元组可以当作记录使用。这个意思是说元组中每个元素都可以看成是一个匿名的字段的值。比如上边例子中列表traveler_ids,其中每个元素都是一个元组,这个时候每个元组对象就是一条记录,记录的第一个字段是国家,第二个字段是护照号码,只不过没有明确的字段名。

元组拆包

如例子中,下边两种用法都是元组拆包,其本质就是用相同数量的变量来接收元组中的元素。

city , year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
'%s/%s' % passport

本质上,可迭代对象都是可以做拆包的,比如列表:

x = ["hello", "world"]
y, z = x
print(y, z)

但是用%字符串格式化进行拆包貌似是元组专用的,至少列表是不行的。即平行赋值的拆包方式适用于任何可迭代对象,而字符串格式化只能用于元组。

        一个经典用法是不借助中间变量交换两个变量的值,其本质也是元组拆包,只不过由于运算符右边只有一个元组参数,因此把小括号给省略了。

可以用 * 来将一个可迭代对象拆包作为函数的参数。divmod函数是计算商和余数,其有两个参数,分别是被除数和除数。这里用 *t 将元组t拆包用作函数的参数。

还可以将元组作为一个函数的返回值,这样就可以方便地用几个变量来接收返回值。比如os.path.split()函数就会返回以路径和最后一个文件名字符串组成的元组(path, last_part):

拆包的时候,可能有些元素我们不感兴趣,因此可以用 _ 来作为占位符。

        python中一个重要的用法是, 在函数参数中用 *args 来让args列表接收不确定数量的参数。这个概念也被扩展到了平行赋值中。

平行赋值时,* 前缀只能用在一个变量名前边,但是可以出现在赋值表达式的任意位置。

嵌套元组拆包

没啥意思,看看例子。

 

具名元组

即collections.namedtuple,collections是python的一个标准库模块,里边存放的都是一些工厂函数,类似C++ STL中的容器或模板类。

        先来个例子观察具名元组的使用:

创建一个具名元组需要两个参数,第一个是类名,第二个是一个类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是空格分隔开的字段名组成的字符串。可以通过字段名或者索引来获取一个字段的信息。

        有意思的一点是,用namedtuple构建的类的实例所消耗的内存跟元组是一样的。流畅的python里的解释是字段名都被存在对应的类里边,那么问题来了,对象是怎么通过字段名来得到某个属性的值的呢?

from collections import namedtuple
import sys

Card = namedtuple("Card", "x y z")
t1 = Card(1, 2, 3)
t2 = (1, 2, 3)
print(sys.getsizeof(t1), sys.getsizeof(t2))

 具名元组还有一些自己专有的属性,比如_fields类属性,_make(iterable)类方法,和实例方法_asdict()。_fields类属性是一个包含这个类所有字段名的元组。类方法_make可以接受一个可迭代对象来生成一个实例,如果不用_make的话,就只能传入很多个参数来构造,而不能直接传入一个可迭代对象。当然也可以用 * 前缀来拆包一个元组再传入构造函数。_asdict()是一个实例方法,用于将具名元组对象的信息以collections.OrderedDict的形式返回,即一个键值对列表的形式。

元组作为不可变列表

除了与增删元素有关的方法以外,元组几乎支持列表其它的所有方法。

 reversed(my_tuple)并不会改变my_tuple,而是将my_tuple逆序然后返回一个新的元组。

四、切片

在python中,像列表list,元组tuple和字符串str这类序列类型都支持切片操作。

切片是左闭右开区间

 切片的时候还可以选择步长,即不连续切片。

需要注意的是如果步长是负的,那么起始索引应该大于结束索引。如下图所示。

 在python中对序列型对象切片的时候是使用了一个切片类的,即slice(start, stop, step)。当我们对一个序列型对象seq进行切片seq[start: stop: step],实际上 start: stop: step 会返回一个切片对象 slice(start, stop, step),这个时候对于切片操作,python解释器实际上会调用特殊方法__getitem__,即seq.__getitem__(slice(start, stop, step))。如下图所示,如果我们经常用某种切片,可以直接定义一个切片对象,就不用每次都输入起始点结束点和步长了。

多维切片和省略

多维切片针对的是多维数据,比如二维切片得到的就是二维数据,自然也就需要两个切片对象才行。在 [ ] 运算符里用逗号隔开两个切片对象就可以得到二维切片了,还可以用逗号隔开两个索引来得到二维索引。比如二维的numpy.ndarray可以用a[i, j]来获取某个元素,a[m : n, k : l]来得到二维切片。[ ] 运算符是与 __getitem__和__setitem__这两个特殊方法相关的。实际上我们在使用二维索引的时候,这两个特殊方法会以元组的方式来接受二维索引,即a.__getitem__((i, j))。

        需要注意的是python的内置序列类型都是一维的,所以是不能用二维索引的,所以对于二维列表来说,索引方式可以是a[i][j],但不能是a[i, j]。

        python还有一个对象是省略,即三个英文句号(...)。它可以用于函数参数列表中,用于表示不确定参数数目,比如 f(a, ..., z),也可以用于切片中,用于切片中时与具体的对象维度有关系,比如a[i, ...],如果a是四维数组,则等价于a[i, :, :, :],即相当于其它三个维度上都是全选的。

修改切片就地改变原序列

对于可修改序列对象来说,其切片与原序列是共享内存的,即修改切片也会修改原序列,但需要注意的是,如果要对切片赋值,那么赋值运算符右侧必须是一个可迭代对象,即使只有一个单独的值,也要转化成可迭代对象。

五、对序列使用 + 和 *

python程序员默认序列是支持 + 和 * 的操作的。 + 用来拼接两个序列,返回一个拼接后的序列。* 用来将一个序列复制几份再拼接起来。+ 和 * 都不修改原有的操作对象。

        * 有一个坑(容器序列,其元素是可变对象,不能用 *,否则复制的都是同一批引用)。如下图例子,my_list是一个列表,其元素也是列表,我们知道列表是容器序列,容器序列中保存的是元素的引用,扁平序列中保存的才是数据。即序列my_list中的元素是对其它可变对象的引用。如果序列中的元素不是对可变对象的引用就没事,比如 my_list=[1, 2, 3, 4, 5, 6]。

那么怎么构建一个包含多个列表的列表呢?用列表推导式。如下图所示,原来列表推导式中用来构建列表的每一项也可以与自变量i无关。注意str是不可变序列,因此 ['_'] * 3 是合法的。

下边这种用 * 的方式是错误的。外层列表看似有三个元素,但是这三个元素都是指向同一个列表的引用。

六、序列的增量赋值 *= 与 +=

 以+=为例讲解,*=类似。

        += 背后的特殊方法是 __iadd__,这个方法是用于就地加法的。但是如果一个类没有实现__iadd__方法,则python会退一步调用__add__。

a += b

对上边例子来说,如果实现了__iadd__方法,且a为可变序列,则会对a进行原地改动,即把b赋值一份接到a上,效果等价于a.extend(b)。但是如果a没有实现__iadd__,则a += b等价于 a = a + b,即计算a + b生成一个新的对象再赋值给a,这个过程b没有变,但是变量名a已经被关联到了新的对象了。

        可变序列都实现了__iadd__方法,用于实现就地加法。不可变序列根本不支持这个操作,因此不会实现此方法。所以不可变对象的 += 和 *= 操作都是相当于把变量名关联到了一个新的对象。对于 *= ,其对应的方法是__imul__。

        一般情况下,对不可变序列进行重复拼接操作效率很低,因为需要构造一个新对象,解释器把原来对象中的元素赋值到先得对象,然后再追加新的元素。但是str类型是个例外,因为字符串 +=操作太普遍了,因此CPython对其进行了优化,为str对象初始化内存的时候,会留出额外的可扩展空间,因此增量操作的时候,不会涉及复制原有字符串到新位置这类操作。

        接下来看一个额外例子,能否改变元组中的可变对象?

如上例子所示,可以看到,元组中有可变对象列表,对列表的改动成功了,但是也抛出了异常。这给了我们一个教训,即不要在元组中放置可变对象。

七、list.sort方法与内置函数sorted

对于序列对象而言,排序是很重要的内容。

        list.sort会就地排序列表,返回值是None,这也是python的一个惯例,对于就地操作的方法返回None,比如random.shuffle也是这样。

        内置函数sorted则会返回一个列表,其接受任何形式的可迭代对象作为参数,但不管接受的是什么参数,其返回值都是列表。

        list.sort和sorted都有两个可选的参数。一个是reverse,如果设置为True,则会降序排列。还有一个可选参数key,这个参数是一个只接受一个参数的函数,其会对序列中的每一个元素进行操作(不改变原始序列中的值),产生结果是排序算法依赖的对比关键字。比如说 key=str.lower,将序列中每个字符都小写化,可以在排序的时候忽略大小写,或者key=len,则会基于字符串长度排序。key的默认值是恒等函数,即默认用元素自己的值来排序。

八、用bisect模块管理已排序的序列

bisect模块主要包含两个函数,bisect和insort,两个函数都利用二分查找算法来在有序序列中查找或插入元素。

用bisect搜索

用法为:position = bisect.bisect(haystack, needle)

其中haystack是一个排序好的序列,needle是待查找的值,返回值position是一个索引值,在索引position之前的索引处数字都是小于needle处的值的,比如下边例子,needle = 3,则position = 1,若needle = 4,则position = 2。

import bisect
haystack = [1, 4, 5, 6, 8, 12, 15, 20]
needle = 4

position = bisect.bisect(haystack, needle)
print(position)

        bisect有两个可选参数用于选定搜索的范围。lo和hi,lo默认是0,hi默认是序列的长度。

        bisect函数其实是bisect_right的别名,还有一个姊妹函数bisect_left。bisect_right返回的位置处是第一个大于needle的索引,bisect_left返回的是第一个小于等于needle的值所在的索引。比如下边例子,bisect_right返回3,bisect_left则返回1。

haystack = [1, 4, 4, 5, 6, 8, 12, 15, 20]
needle = 4

用bisect.insort插入新元素

用法:insort(seq, item)

        seq是排好序的有序序列,item是我们要插入的元素,用insort可以把变量item插入到序列seq中,并保持seq有序。insort相当于先查找再插入,即等价于先用bisect再用insert之类的插入。

        insort跟bisect一样,有lo和hi两个可选参数控制查找范围,也有个变体insort_left,此变体背后使用bisect_left,即在左边插入,insort则是在右边插入。

九、替换列表的数据结构

有时候列表不是最优选。比如要存放1000万个浮点数,数组(array)的效率要高很多,因为数组背后存放的不是float对象,而是数字的机器翻译,即字节表述。再比如,若要对序列频繁进行先入先出,deque(双端队列)的速度应该更快。

数组

这里指的是python标准库中的数组,即array.array。而不是numpy数组。

        如果我们想要一个只包含数字的列表,那么数组更合适。数组支持所有跟可变序列相关的操作,包括 .pop、.insert、.extend。数组还提供从文件读取和存入文件的更快的方法,如 .frombytes和 .tofile。

        创建数组需要一个类型码,类型码用来表示再底层的C语言应该存放怎样的数据类型。比如array('b')创建出的数组就只能存放一个字节大小的整数,‘b’代表有符号的字符,大小范围为 -128 到 127。这样指向以后,数组中就不能存放其它类型的数据。

        例题:创建一个1000万个浮点数的数组,把数组保存文件里,再从文件读取此数组。

from array import array
from random import random

floats = array('d', (random() for i in range(10**2))) # 生成器表达式可以用于生成任意序列类型,'d'表示是双精度浮点数对象,跟python内置类型不同,array.array是需要指定数值精度的
print(floats[-1]) # 查看数组中最后一个元素
fp = open('floats.bin', 'wb') # 以二进制可写的方式打开一个文件,如果文件不存在,则创建该文件
floats.tofile(fp) # 用.tofile方法把数组中的内容写入到二进制文件floats.bin中
fp.close() # 关闭文件
floats2 = array('d') # 再创建一个存储双精度浮点数的数组对象
fp = open('floats.bin', 'rb') # 打开上边关闭的文件
floats2.fromfile(fp, 10**2) # 用.fromfile方法从打开的文件中读取10**2个元素到新建的数组
fp.close() # 关闭文件
print(floats2[-1]) # 查看第二个数组的最后一个元素
print(floats2 == floats) # 判断两个数组是否相等

从以上例子可以看出,用python数组array.array是能够很方便地与文件进行交互的,通过tofile方法将数组内容存储到文件,再通过fromfile方法将文件中内容读取到数组。上边我们把浮点数写入读出二进制文件都要比文本文件快很多倍。而且二进制文件的大小也要更小一点。除了用array.array的tofile和fromfile方法外,还可以用pickle模块的dump方法将对象存储到文件,或者load方法从文件中加载信息到某个对象。pickle是python专用的,其文件后缀一般是 .pkl,可以选择是保存成文本文件或二进制文件。

 

python中的array.array非常类似C中的数组,也是要提供数据类型。需要注意的是array数组不支持list.sort这种原地排序方法,要给array数组排序的话只能先用sorted生成一个排序好的新数组,再让原数组名关联此新数组。对于查找和插入则仍然可以使用bisect模块来完成。

内存视图

memoryview是一个内置类,能让用户在不复制内容的情况下操作同一个数组的不同切片,本质上其实跟torch中的view方法思想有类似之处,就是从不同的角度看待同一块内存区域的数据。

from array import array
from random import random

numbers = array('h', [i for i in range(-2, 3)]) # 列表推导式生成数组,数组元素是十六进制整数
memv = memoryview(numbers) # 从内存角度看待该数组
print(len(memv), memv.tolist()) # 打印出数组长度于具体值,可以看出跟number一样
print(memv[0]) # 数组的第一个元素就是现在内存视图的第一个元素
memv_oct = memv.cast('B') # memv.cast类型强制转换,改成以无符号字符的角度来看待numbers数组的那一块内存
print(len(memv_oct), memv_oct.tolist()) # 因为一个无符号字符占八个字节,原先十六进制中的一个数字被拆分成了两个,因此内存视图长度加倍
memv_oct[5] = 4 # 改变内存视图的某个索引的值,可以影响到原数组,因为是共享内存的。
print(numbers)

NumPy和SciPy

numpy实现了多维同质数组和矩阵,scipy是基于numpy的库。numpy也可以轻易实现数组对象与文件的交互。numpy.save()用于将一个多维数组保存到一个二进制文件中。

双向队列和其它形式的队列

python中的列表可以当作栈或者队列使用。

        列表模拟队列:.append()插入元素,.pop(0)删除元素,即模拟了先进先出。

        列表模拟栈:.append()插入元素,.pop(l.size() - 1)删除元素,即模拟了后进先出。

        缺点是删除列表第一个元素之类的操作会移动列表中的所有元素,这些操作是非常耗时的。

collections.deque

        collections.deque类是一个线程安全、可以快速从两端添加或删除元素的数据类型,deque即双端队列。

需要注意的是在构造一个双端队列对象时有一个可选参数maxlen,代表这个队列可以容纳的元素的数量,这个属性一旦设定就不可修改。设定了这个属性以后,如果添加元素超出了容量,则会自动删除一部分元素,从左边插入就从右边删除,从右边插入就从左边删除。

        append和popleft都是原子操作,也就是说deque可以在多线程程序中当作先进先出的队列使用,即线程安全。

        还有一些其它的python库提供了队列的实现。

queue

multiprocessing

 asyncio

heapq

《流畅的python》读书笔记 《流畅的python》这本书值得推荐,认真读完2篇,对python的理解提高一大截。本书属于python进阶书,不适合入门读物。另外还有2本进阶书《python cookbook》和《Effective Python:编写高质量Python代码的59个有效方法》。下面是本书的读书笔记,其他2本后面陆续补充。 阅读详情

相关推荐

《Python学习手册第4版》PDF源代码+《流畅的Python》PDF思维导图

看到第38章了,整体感觉解释详细,例子丰富;关于Python语言本身的讲解全面详尽而又循序渐进不断重复,同时详述语言现象背后的机制和原理;除语言本身,还包含编程实践和设计以及高级主题。边看边写代码。不然看了会忘,也不会发现细节问题。边看边梳理总结。先看代码,再看文字解释。因为Python本来就是自说明,例子也好懂,所以这样干可以避免枯燥,加速阅读。循序渐进,重要的主题会渐进式呈现,并随后...

denglubian8487的博客 2754

【NumPy】深入解析numpy中的save方法

NumPy 的save方法为数据的持久化提供了一种简单而有效的方式。本文介绍了如何使用 NumPy 进行数据的保存,包括不同保存函数的使用。希望本文能够帮助您更好地管理和存储您的数据。

2402_83361138的博客 2488

《流畅的Python》读书笔记(二)

更专业点-《流畅的Python》读书笔记(二)第2章 序列构成的数组python标准库用C实现了丰富的序列类型列表推导和生成器表达式元组不仅仅是不可变的列表切片序列运算符几个重要的模块当列表不是首选时 第2章 序列构成的数组 python标准库用C实现了丰富的序列类型 可分类成: 容器序列(存放对象的引用),如:list、tuple和collections.deque 扁平序列(存放的是值,是一...

george_zhou_2016的博客 254

Numpy中数据的常用的保存与读取方法

Numpy中数据的常用的保存与读取方法 https://www.cnblogs.com/wushaogui/p/9142019.html 保存为二进制文件(.npy/.npz) 1.numpy.save 保存一个数组到一个二进制的文件中,保存格式是.npy 参数介绍 numpy.save(file, arr, allow_pickle=True, fix_imports=True) file:文件名/文件路径 arr:要存储的数组 allow_pickle:布尔值,允许使用Python pick

qq_43760191的博客 1万+

图解说明JLink驱动与目标板电源匹配的关键细节

深入讲解JLink驱动安装及使用过程中,如何正确匹配目标板电源,避免常见通信故障。通过图解方式清晰展示关键连接细节,确保调试稳定可靠,是嵌入式开发中不可或缺的实战经验分享。

weixin_42173218的博客 431

WorkBuddy实战技巧:搭建高效AI工作台与自动化流程

在数字化办公场景中,AI工作台正逐渐成为提升个人与团队效率的关键工具。它不同于简单的聊天机器人,而是通过集成技能包(Skill)、自动化触发与文档处理能力,把重复性任务如信息提取、周报生成、数据表格整理等变为标准化流程。其核心原理在于将用户需求拆解为可执行的指令链,并借助本地脚本、API调用及定时任务实现“对话即操作”的智能协作。这种技术价值不仅适用于程序员,更惠及运营、客服、行政、科研等日常与文字数据打交道的群体。从自动签到、会议纪要,到批量处理Excel与合同要点提取,AI工作台的应用场景已覆盖多个高频

weixin_42547431的博客 334

Python:切片语法左闭右开 [,)

左闭右开的原则。这种设计在处理子集时非常方便,尤其是对于范围的选择。

Ethan_Rich的博客 1467

cordic算法的FPGA实现

cordic 算法的MATLAB仿真及verilog实现

qq_38360574的博客 1676

numpy保存数据

保存numpy array数据 利用numpy.save()函数将array保存为.npy格式的数据 numpy中的数据I/O可以简单地通过save函数实现: import numpy as np a = np.array(range(100)) np.save('where/you/wanto/store/output',a) #numpy 会自动加上.npy后缀 这时在目录中得...

TomRen 1万+

使用GitLab+Drone CI持续集成自动部署web项目,图文详细

kind: pipeline # 定义对象类型,还有secret和signature两种类型 type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型 name: mall-tiny-drone # 定义流水线名称 steps: # 定义流水线执行步骤,这些步骤将顺序执行 - name: package # 流水线名称 image: maven:3-jdk-8 # 定义创建容器的Docker镜像 volumes: # 将容器内目录挂载到宿主机,仓库

4105

材料仿真软件:Materials Studio_(14).电学性质计算

设置计算参数,包括 k 点网格、交换相关泛函等。

kkchenjj的博客 1864

流畅的Python笔记

比如,要存放 1000 万个浮点数的话,数组(array)的效率要高得多,因为数组在背后存的并不是 float 对象,而是数字的机器翻译,也就是字节表述。构造方法或 [:] 做的是浅复制(即复制了最外层容器,副本中的元素是源容器中元素的引用)。综上,闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定。注意,一般来说,深复制不是件简单的事。其实,闭包指延伸了作用域的函数,其中包含函数定义体中引用、但是不在定义体中定义的非全局变量。

ccnuacmhdu的博客 1086

ue 蓝图 c++ websocket 事件回调

ue 蓝图 c++ websocket 事件回调

jacke121的专栏 166

《流畅的Python》学习笔记(一)——数据结构

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 第2章 序列构成的数组前言一、内置序列类型概览2.1、列表推导和生成器表达式2.1.1 列表推导2.1.2 生成器表达式总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、内置序列类型概览 容器序列 list(列表) tuple(元组) collections

..L.. 340

QProgressBar:常用接口、样式表及自定义进度条实现

在Qt开发中,QProgressBar 是一个非常常用的控件,用于显示任务的进度。无论是文件下载、数据处理还是其他耗时操作,QProgressBar 都能直观地展示当前进度。本文将详细介绍QProgressBar 的使用方法,包括常用接口、样式表设置,并额外补充一个自定义进度条的C++实现。

u011186532的专栏 1012

第二节:Vben Admin 登录逻辑梳理和对接后端准备

第一节,我们已经配置了前端环境,运行起来了我们的Vben Admin的项目。本节内容,我们先熟悉下项目的目录和文件,然后开始准备对接后端程序路由在 src/router页面在 sr/views本节前端登录逻辑梳理完成了,后端只要在/api/login 接口编写返回逻辑,前后段就可以打通了,具体详情我们下一节介绍。

cuiwin的专栏 5084

《流畅的python》学习笔记及书评

《流畅的python》学习笔记 文章目录《流畅的python》学习笔记写在前面1. Python数据模型1.1 特殊方法2. 序列构成的数组2.1 内置序列类型2.2 列表推导和生成器表达式2.3 元组不仅仅是不可变的列表2.4 切片2.5 增量赋值2.6 排序2.7 数组、内存视图、NumPy和队列3. 字典和集合3.1 泛映射类型和字典推导3.2 常见的映射方法3.3 映射的弹性键查询3.4 字典的变种3.5 集合3.6 dict和set的背后4. 文本和字节序列4.1 字符和字节4.2 编码和解码4.

李英俊小朋友 2463

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【免费下载】 《流畅的Python》(第2版)学习笔记资源下载

《流畅的Python》(第2版)学习笔记资源下载 【下载地址】流畅的Python第2版学习笔记资源下载 《流畅的Python》(第2版)学习笔记资源下载本仓库提供《流畅的Python》(第2版)学习笔记的下载资源,帮助读者更好地理解和掌握书中的内容 ...

gitblog_09729的博客 990

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

《流畅的python》学习笔记

《流畅的python》学习笔记(一)起步第一章 python数据模型__len__方法 起步 从事软件开发14年半,前12年一直用C/C++写服务器端程序,主要涉及作业、流程调度和通信等等程序,从纯写代码到大系统的架构设计,刨过各种坑,战战兢兢的在软件行业前行,从不放弃学习,也从学习中得到快乐。从事传统软件行业,公司的技术水平及其有限,作为软件公司,公司领导更看重的是业务,对技术,尤其是软件技术并...

weixin_43472507的博客 445

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

《流畅的Python第二版》读书笔记

《流畅的Python 第二版》读书笔记。

日积月累,天道酬勤 4185

《流畅的python》阅读笔记

搬运工:《流畅的python》阅读笔记

Salmon_lee的博客 130

流畅的Python阅读笔记

五一快乐的时光总是飞快了,不知多久没有拿起键盘写文章了,最近公司有Python的需求,想着复习下Python吧,然后就买了本Python的书籍 书名:下面是整理的一个阅读笔记,大家自行查阅,主要是做一个记录,记录下自己认为重要的部分。

程序员小刘 1535

流畅的python阅读笔记

流畅的python阅读笔记

weixin_41258222的博客 166

看流畅的python感觉有难度_《流畅的Python》读书笔记

第一部分:序幕第1章:Python数据模型通过实现特殊方法,自定义数据类型可以表现得和内置类型一样;__repr__方便调试和记录日志,__str__方便用户看;序列数据类型特殊方法使用最多;第二部分:数据结构第2章:序列构成的数组系列类型可分为 可变和不可变、扁平序列和容器序列;列表推导生成器表达式提供了灵活构建和初始化序列的方式;元组、切片、array.array、collections.de...

weixin_39580682的博客 234

《流畅的 Python》笔记小记(第二版)

使用 notion 来记录我的笔记,详情请参阅该链接:流畅的 Python 第二版

息衍的博客 583

流畅的python读书笔记_流畅的Python_读书笔记(一)

这周正式开始阅读另一本Python的书籍《流畅的Python》,这周阅读的部分有Python数据模型、序列构成的数组和字典和集合。下面分享我的读书笔记。首先书中用一个简单的代码展示了如何实现__getitem__和__len__特殊方法。针对上述代码,我最大的启发就是Python特殊方法真的很有用。通过实现__getitem__和__len__特殊方法,我们直接可以用len()计算卡片的长度,而且...

weixin_39790760的博客 287
上一篇: 笔试题------查找积分对
下一篇: 流畅的python笔记(三)字典和集合
罗古洞的女婿
博客等级 码龄10年 1117粉丝 125原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值