cevalokas

personal website

Not because they are easy, but because they are hard.


python碎碎念2

目录

基础数据类型

Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。

在 Python 中,变量就是变量,它没有类型,我们所说的”类型”是变量所指的内存中对象的类型。

等号(=)用来给变量赋值。

等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。例如:

实例(Python 3.0+)

#!/usr/bin/python3  
  
counter = 100          # 整型变量  
miles   = 1000.0       # 浮点型变量  
name    = "runoob"     # 字符串  
  
print (counter)  
print (miles)  
print (name)  

  

执行以上程序会输出如下结果:

100 1000.0 runoob

多个变量赋值

Python允许你同时为多个变量赋值。例如:

a = b = c = 1

以上实例,创建一个整型对象,值为 1,从后向前赋值,三个变量被赋予相同的数值。

您也可以为多个对象指定多个变量。例如:

a, b, c = 1, 2, "runoob"

以上实例,两个整型对象 1 和 2 的分配给变量 a 和 b,字符串对象 “runoob” 分配给变量 c。


标准数据类型

Python3 中常见的数据类型有:

  • Number(数字)
  • String(字符串)
  • bool(布尔类型)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

Python3 的六个标准数据类型中:

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

此外还有一些高级的数据类型,如: 字节数组类型(bytes)。


Number(数字)

Python3 支持 int、float、bool、complex(复数)

在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。

像大多数语言一样,数值类型的赋值和计算都是很直观的。

内置的 type() 函数可以用来查询变量所指的对象类型。

>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>

此外还可以用 isinstance 来判断:

数值运算


>>> 5 + 4  # 加法  
9  
>>> 4.3 - 2 # 减法  
2.3  
>>> 3 * 7  # 乘法  
21  
>>> 2 / 4  # 除法,得到一个浮点数  
0.5  
>>> 2 // 4 # 除法,得到一个整数  
0  
>>> 17 % 3 # 取余  
2  
>>> 2 ** 5 # 乘方  
32  

注意:

  • 1、Python可以同时为多个变量赋值,如a, b = 1, 2。
  • 2、一个变量可以通过赋值指向不同类型的对象。
  • 3、数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。
  • 4、在混合计算时,Python会把整型转换成为浮点数。

数值类型实例

int float complex
10 0.0 3.14j
100 15.20 45.j
-786 -21.9 9.322e-36j
080 32.3e+18 .876j
-0490 -90. -.6545+0J
-0x260 -32.54e100 3e+26J
0x69 70.2E-12 4.53e-7j

Python 还支持复数,复数由实数部分和虚数部分构成,可以用 a + bj,或者 complex(a,b) 表示, 复数的实部 a 和虚部 b 都是浮点型。


String(字符串)

Python中的字符串用单引号 ’ 或双引号 ” 括起来,同时使用反斜杠 \ 转义特殊字符。

字符串的截取的语法格式如下:

变量[头下标:尾下标]

索引值以 0 为开始值,-1 为从末尾的开始位置。

加号 + 是字符串的连接符, 星号 * 表示复制当前字符串,与之结合的数字为复制的次数。实例如下:

#!/usr/bin/python3  
  
str = 'Runoob'  # 定义一个字符串变量  
  
print(str)           # 打印整个字符串  
print(str[0:-1])     # 打印字符串第一个到倒数第二个字符(不包含倒数第一个字符)  
print(str[0])        # 打印字符串的第一个字符  
print(str[2:5])      # 打印字符串第三到第五个字符(包含第五个字符)  
print(str[2:])       # 打印字符串从第三个字符开始到末尾  
print(str * 2)       # 打印字符串两次  
print(str + "TEST")  # 打印字符串和"TEST"拼接在一起  

执行以上程序会输出如下结果:

Runoob Runoo R noo noob RunoobRunoob RunoobTEST

Python 使用反斜杠 \ 转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:

与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如 word[0] = ‘m’ 会导致错误。

注意:

  • 1、反斜杠可以用来转义,使用r可以让反斜杠不发生转义。
  • 2、字符串可以用+运算符连接在一起,用*运算符重复。
  • 3、Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。
  • 4、Python中的字符串不能改变。

    Python 转义字符

在需要在字符中使用特殊字符时,python 用反斜杠 \ 转义字符。如下表:

转义字符 描述 实例
(在行尾时) 续行符 »> print(“line1 <br>… line2 <br>… line3”)
line1 line2 line3
»>
|反斜杠符号 »> print(“\”)
|
 
' 单引号 »> print(‘'’)
" 双引号 »> print(“"”)
\a 响铃 »> print(“\a”)

执行后电脑有响声。
\b 退格(Backspace) »> print(“Hello \b World!”)
Hello World!
\000 »> print(“\000”)

»>
\n 换行 »> print(“\n”)

»>
\v 纵向制表符 »> print(“Hello \v World!”)
Hello
World!
»>
\t 横向制表符 »> print(“Hello \t World!”)
Hello      World!
»>
\r 回车,将 \r 后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将 \r 后面的内容完全替换完成。 »> print(“Hello\rWorld!”)
World!
»> print(‘google runoob taobao\r123456’)
123456 runoob taobao
\f 换页 »> print(“Hello \f World!”)
Hello
World!
»>
\yyy 八进制数,y 代表 0~7 的字符,例如:\012 代表换行。 »> print(“\110\145\154\154\157\40\127\157\162\154\144\41”)
Hello World!
\xyy 十六进制数,以 \x 开头,y 代表的字符,例如:\x0a 代表换行 »> print(“\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21”)
Hello World!
\other 其它的字符以普通格式输出  

使用 \r 实现百分比进度:

import time  
  
for i in range(101):  
    print("\r{:3}%".format(i),end=' ')  
    time.sleep(0.05)  

以下实例,我们使用了不同的转义字符来演示单引号、换行符、制表符、退格符、换页符、ASCII、二进制、八进制数和十六进制数的效果:

print('\'Hello, world!\'')  # 输出:'Hello, world!'  
  
print("Hello, world!\nHow are you?")  # 输出:Hello, world!  
                                        #       How are you?  
  
print("Hello, world!\tHow are you?")  # 输出:Hello, world!    How are you?  
  
print("Hello,\b world!")  # 输出:Hello world!  
  
print("Hello,\f world!")  # 输出:  
                           # Hello,  
                           #  world!  
  
print("A 对应的 ASCII 值为:", ord('A'))  # 输出:A 对应的 ASCII 值为: 65  
  
print("\x41 为 A 的 ASCII 代码")  # 输出:A 为 A 的 ASCII 代码  
  
decimal_number = 42  
binary_number = bin(decimal_number)  # 十进制转换为二进制  
print('转换为二进制:', binary_number)  # 转换为二进制: 0b101010  
  
octal_number = oct(decimal_number)  # 十进制转换为八进制  
print('转换为八进制:', octal_number)  # 转换为八进制: 0o52  
  
hexadecimal_number = hex(decimal_number)  # 十进制转换为十六进制  
print('转换为十六进制:', hexadecimal_number) # 转换为十六进制: 0x2a  

Python 字符串运算符

下表实例变量 a 值为字符串 “Hello”,b 变量值为 “Python”:

操作符 描述 实例
+ 字符串连接 a + b 输出结果: HelloPython
* 重复输出字符串 a*2 输出结果:HelloHello
[] 通过索引获取字符串中字符 a[1] 输出结果 e
[ : ] 截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。 a[1:4] 输出结果 ell
in 成员运算符 - 如果字符串中包含给定的字符返回 True ‘H’ in a 输出结果 True
not in 成员运算符 - 如果字符串中不包含给定的字符返回 True ‘M’ not in a 输出结果 True
r/R 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 print( r’\n’ )
print( R’\n’ )
% 格式字符串 请看下一节内容。

Python 字符串格式化

Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。

在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。

#!/usr/bin/python3 print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

以上实例输出结果:

我叫 小明 今年 10 岁!

python字符串格式化符号:

符   号 描述
%c 格式化字符及其ASCII码
%s 格式化字符串
%d 格式化整数
%u 格式化无符号整型
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%e 用科学计数法格式化浮点数
%E 作用同%e,用科学计数法格式化浮点数
%g %f和%e的简写
%G %f 和 %E 的简写
%p 用十六进制数格式化变量的地址

格式化操作符辅助指令:

符号 功能
* 定义宽度或者小数点精度
- 用做左对齐
+ 在正数前面显示加号( + )
在正数前面显示空格
# 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’)
0 显示的数字前面填充’0’而不是默认的空格
% ’%%’输出一个单一的’%’
(var) 映射变量(字典参数)
m.n. m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)

Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。


Python三引号

python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。实例如下

#!/usr/bin/python3 
para_str = """这是一个多行字符串的实例 多行字符串可以使用制表符 TAB ( \t )。 也可以使用换行符 [ \n ]。 """ 
print (para_str)

以上实例执行结果为:

这是一个多行字符串的实例
多行字符串可以使用制表符
TAB (    )。
也可以使用换行符 [ 
 ]。

三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的。

一个典型的用例是,当你需要一块HTML或者SQL时,这时用字符串组合,特殊字符串转义将会非常的繁琐。

f-string

f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。

之前我们习惯用百分号 (%):

>>> name = 'Runoob'  
>>> 'Hello %s' % name  
'Hello Runoob'  

f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:

>>> name = 'Runoob'  
>>> f'Hello {name}'  # 替换变量  
'Hello Runoob'  
>>> f'{1+2}'         # 使用表达式  
'3'  
  
>>> w = {'name': 'Runoob', 'url': 'www.runoob.com'}  
>>> f'{w["name"]}: {w["url"]}'  
'Runoob: www.runoob.com'  

用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。

在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:

>>> x = 1  
>>> print(f'{x+1}')   # Python 3.6  
2  
  
>>> x = 1  
>>> print(f'{x+1=}')   # Python 3.8  
x+1=2  

Unicode 字符串

在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u

在Python3中,所有的字符串都是Unicode字符串。

Python 的字符串内建函数

Python 的字符串常用内建函数如下:

序号 方法及描述
1 capitalize()
将字符串的第一个字符转换为大写
2 center(width, fillchar)

返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。
3 count(str, beg= 0,end=len(string))


返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
4 bytes.decode(encoding=”utf-8”, errors=”strict”)


Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。
5 encode(encoding=’UTF-8’,errors=’strict’)


以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’
6 endswith(suffix, beg=0, end=len(string))
检查字符串是否以 suffix 结束,如果 beg 或者 end 指定则检查指定的范围内是否以 suffix 结束,如果是,返回 True,否则返回 False。
7 expandtabs(tabsize=8)


把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。
8 find(str, beg=0, end=len(string))


检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1
9 index(str, beg=0, end=len(string))


跟find()方法一样,只不过如果str不在字符串中会报一个异常。
10 isalnum()


检查字符串是否由字母和数字组成,即字符串中的所有字符都是字母或数字。如果字符串至少有一个字符,并且所有字符都是字母或数字,则返回 True;否则返回 False。
11 isalpha()


如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False
12 isdigit()


如果字符串只包含数字则返回 True 否则返回 False..
13 islower()


如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
14 isnumeric()


如果字符串中只包含数字字符,则返回 True,否则返回 False
15 isspace()


如果字符串中只包含空白,则返回 True,否则返回 False.
16 istitle()


如果字符串是标题化的(见 title())则返回 True,否则返回 False
17 isupper()


如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
18 join(seq)


以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
19 len(string)


返回字符串长度
20 ljust(width[, fillchar])


返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。
21 lower()


转换字符串中所有大写字符为小写.
22 lstrip()


截掉字符串左边的空格或指定字符。
23 maketrans()


创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
24 max(str)


返回字符串 str 中最大的字母。
25 min(str)


返回字符串 str 中最小的字母。
26 replace(old, new [, max])


把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
27 rfind(str, beg=0,end=len(string))


类似于 find()函数,不过是从右边开始查找.
28 rindex( str, beg=0, end=len(string))


类似于 index(),不过是从右边开始.
29 rjust(width,[, fillchar])


返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
30 rstrip()


删除字符串末尾的空格或指定字符。
31 split(str=””, num=string.count(str))


以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串
32 splitlines([keepends])


按照行(‘\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
33 startswith(substr, beg=0,end=len(string))


检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。
34 strip([chars])


在字符串上执行 lstrip()和 rstrip()
35 swapcase()


将字符串中大写转换为小写,小写转换为大写
36 title()


返回”标题化”的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
37 translate(table, deletechars=””)


根据 table 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中
38 upper()


转换字符串中的小写字母为大写
39 zfill (width)


返回长度为 width 的字符串,原字符串右对齐,前面填充0
40 isdecimal()


检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。

bool(布尔类型)

布尔类型即 True 或 False。

在 Python 中,True 和 False 都是关键字,表示布尔值。

布尔类型可以用来控制程序的流程,比如判断某个条件是否成立,或者在某个条件满足时执行某段代码。

布尔类型特点:

  • 布尔类型只有两个值:True 和 False。

  • bool 是 int 的子类,因此布尔值可以被看作整数来使用,其中 True 等价于 1。

  • 布尔类型可以和其他数据类型进行比较,比如数字、字符串等。在比较时,Python 会将 True 视为 1,False 视为 0。

  • 布尔类型可以和逻辑运算符一起使用,包括 and、or 和 not。这些运算符可以用来组合多个布尔表达式,生成一个新的布尔值。

  • 布尔类型也可以被转换成其他数据类型,比如整数、浮点数和字符串。在转换时,True 会被转换成 1,False 会被转换成 0。

  • 可以使用 bool() 函数将其他类型的值转换为布尔值。以下值在转换为布尔值时为 FalseNoneFalse、零 (00.00j)、空序列(如 ''()[])和空映射(如 {})。其他所有值转换为布尔值时均为 True

注意: 在 Python 中,所有非零的数字和非空的字符串、列表、元组等数据类型都被视为 True,只有 0、空字符串、空列表、空元组等被视为 False。因此,在进行布尔类型转换时,需要注意数据类型的真假性。


List(列表)

List(列表) 是 Python 中使用最频繁的数据类型。

列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。

列表是写在方括号 [] 之间、用逗号分隔开的元素列表。

和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。

列表截取的语法格式如下:

变量[头下标:尾下标]

索引值以 0 为开始值,-1 为从末尾的开始位置。

加号 + 是列表连接运算符,星号 * 是重复操作。如下实例:

实例

#!/usr/bin/python3  
  
list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ]  # 定义一个列表  
tinylist = [123, 'runoob']  
  
print (list)            # 打印整个列表  
print (list[0])         # 打印列表的第一个元素  
print (list[1:3])       # 打印列表第二到第四个元素(不包含第四个元素)  
print (list[2:])        # 打印列表从第三个元素开始到末尾  
print (tinylist * 2)    # 打印tinylist列表两次  
print (list + tinylist)  # 打印两个列表拼接在一起的结果  

以上实例输出结果:

[‘abcd’, 786, 2.23, ‘runoob’, 70.2] abcd [786, 2.23] [2.23, ‘runoob’, 70.2] [123, ‘runoob’, 123, ‘runoob’] [‘abcd’, 786, 2.23, ‘runoob’, 70.2, 123, ‘runoob’]

与Python字符串不一样的是,列表中的元素是可以改变的:

List 内置了有很多方法,例如 append()、pop() 等等,这在后面会讲到。

注意:

  • 1、列表写在方括号之间,元素用逗号隔开。
  • 2、和字符串一样,列表可以被索引和切片。
  • 3、列表可以使用 + 操作符进行拼接。
  • 4、列表中的元素是可以改变的。

Python 列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串:

如果第三个参数为负数表示逆向读取,以下实例用于翻转字符串:

def reverseWords(input):  
       
    # 通过空格将字符串分隔符,把各个单词分隔为列表  
    inputWords = input.split(" ")  
   
    # 翻转字符串  
    # 假设列表 list = [1,2,3,4],    
    # list[0]=1, list[1]=2 ,而 -1 表示最后一个元素 list[-1]=4 ( 与 list[3]=4 一样)  
    # inputWords[-1::-1] 有三个参数  
    # 第一个参数 -1 表示最后一个元素  
    # 第二个参数为空,表示移动到列表末尾  
    # 第三个参数为步长,-1 表示逆向  
    inputWords=inputWords[-1::-1]  
   
    # 重新组合字符串  
    output = ' '.join(inputWords)  
       
    return output  
   
if __name__ == "__main__":  
    input = 'I like runoob'  
    rw = reverseWords(input)  
    print(rw)  

输出结果为:

runoob like I

更新列表

你可以对列表的数据项进行修改或更新,你也可以使用 append() 方法来添加列表项,如下所示:

#!/usr/bin/python3  
  
list = ['Google', 'Runoob', 1997, 2000]  
  
print ("第三个元素为 : ", list[2])  
list[2] = 2001  
print ("更新后的第三个元素为 : ", list[2])  
  
list1 = ['Google', 'Runoob', 'Taobao']  
list1.append('Baidu')  
print ("更新后的列表 : ", list1)  

以上实例输出结果:

第三个元素为 : 1997 更新后的第三个元素为 : 2001 更新后的列表 : [‘Google’, ‘Runoob’, ‘Taobao’, ‘Baidu’]

删除列表元素

可以使用 del 语句来删除列表中的元素,如下实例:

#!/usr/bin/python3  
   
list = ['Google', 'Runoob', 1997, 2000]  
   
print ("原始列表 : ", list)  
del list[2]  
print ("删除第三个元素 : ", list)  

以上实例输出结果:

原始列表 : [‘Google’, ‘Runoob’, 1997, 2000] 删除第三个元素 : [‘Google’, ‘Runoob’, 2000]

注意:我们会在接下来的章节讨论 remove() 方法的使用

Python列表脚本操作符

列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。

如下所示:

Python 表达式 结果 描述
len([1, 2, 3]) 3 长度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 组合
[‘Hi!’] * 4 [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] 重复
3 in [1, 2, 3] True 元素是否存在于列表中
for x in [1, 2, 3]: print(x, end=” “) 1 2 3 迭代

Python 列表截取与拼接

Python 的列表截取与字符串操作类似,如下所示:

L=[‘Google’, ’Runoob’, ’Taobao’]

操作:

|Python 表达式|结果|描述| |—|—|—| |L[2]|’Taobao’|读取第三个元素| |L[-2]|’Runoob’|从右侧开始读取倒数第二个元素: count from the right| |L[1:]|[‘Runoob’, ‘Taobao’]|输出从第二个元素开始后的所有元素|

>>> L=['Google', 'Runoob', 'Taobao']  
>>> L[2]  
'Taobao'  
>>> L[-2]  
'Runoob'  
>>> L[1:]  
['Runoob', 'Taobao']  
>>>  

列表还支持拼接操作:

>>> squares = [1, 4, 9, 16, 25]  
>>> squares += [36, 49, 64, 81, 100]  
>>> squares  
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]  
>>>  

嵌套列表

使用嵌套列表即在列表里创建其它列表,例如:

>>> a = ['a', 'b', 'c']  
>>> n = [1, 2, 3]  
>>> x = [a, n]  
>>> x  
[['a', 'b', 'c'], [1, 2, 3]]  
>>> x[0]  
['a', 'b', 'c']  
>>> x[0][1]  
'b'  

Python列表函数&方法

Python包含以下函数:

序号 函数
1 len(list)
列表元素个数
2 max(list)
返回列表元素最大值
3 min(list)
返回列表元素最小值
4 list(seq)
将元组转换为列表

Python包含以下方法:

序号 方法
1 list.append(obj)
在列表末尾添加新的对象
2 list.count(obj)
统计某个元素在列表中出现的次数
3 list.extend(seq)
在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4 list.index(obj)
从列表中找出某个值第一个匹配项的索引位置
5 list.insert(index, obj)
将对象插入列表
6 list.pop([index=-1])
移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7 list.remove(obj)
移除列表中某个值的第一个匹配项
8 list.reverse()
反向列表中元素
9 list.sort( key=None, reverse=False)
对原列表进行排序
10 list.clear()
清空列表
11 list.copy()
复制列表|

Tuple(元组)

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。

元组中的元素类型也可以不相同:

实例

#!/usr/bin/python3  
  
tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2  )  
tinytuple = (123, 'runoob')  
  
print (tuple)             # 输出完整元组  
print (tuple[0])          # 输出元组的第一个元素  
print (tuple[1:3])        # 输出从第二个元素开始到第三个元素  
print (tuple[2:])         # 输出从第三个元素开始的所有元素  
print (tinytuple * 2)     # 输出两次元组  
print (tuple + tinytuple) # 连接元组  

以上实例输出结果:

(‘abcd’, 786, 2.23, ‘runoob’, 70.2) abcd (786, 2.23) (2.23, ‘runoob’, 70.2) (123, ‘runoob’, 123, ‘runoob’) (‘abcd’, 786, 2.23, ‘runoob’, 70.2, 123, ‘runoob’)

元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置。也可以进行截取(看上面,这里不再赘述)。

其实,可以把字符串看作一种特殊的元组。

虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。

构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:

tup1 = () # 空元组 tup2 = (20,) # 一个元素,需要在元素后添加逗号

如果你想创建只有一个元素的元组,需要注意在元素后面添加一个逗号,以区分它是一个元组而不是一个普通的值,这是因为在没有逗号的情况下,Python会将括号解释为数学运算中的括号,而不是元组的表示。

如果不添加逗号,如下所示,它将被解释为一个普通的值而不是元组:

not_a_tuple = (42)

这样的话,not_a_tuple 将是整数类型而不是元组类型。

string、list 和 tuple 都属于 sequence(序列)。

注意:

  • 1、与字符串一样,元组的元素不能修改。
  • 2、元组也可以被索引和切片,方法一样。
  • 3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。
  • 4、元组也可以使用 + 操作符进行拼接。

Set(集合)

Python 中的集合(Set)是一种无序、可变的数据类型,用于存储唯一的元素。

集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。

在 Python 中,集合使用大括号 {} 表示,元素之间用逗号 , 分隔。

另外,也可以使用 set() 函数创建集合。

注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

创建格式:

parame = {value01,value02,…} 或者 set(value)

实例

#!/usr/bin/python3  
  
sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}  
  
print(sites)   # 输出集合,重复的元素被自动去掉  
  
# 成员测试  
if 'Runoob' in sites :  
    print('Runoob 在集合中')  
else :  
    print('Runoob 不在集合中')  
  
  
# set可以进行集合运算  
a = set('abracadabra')  
b = set('alacazam')  
  
print(a)  
  
print(a - b)     # a 和 b 的差集  
  
print(a | b)     # a 和 b 的并集  
  
print(a & b)     # a 和 b 的交集  
  
print(a ^ b)     # a 和 b 中不同时存在的元素  

以上实例输出结果:

{‘Zhihu’, ‘Baidu’, ‘Taobao’, ‘Runoob’, ‘Google’, ‘Facebook’} Runoob 在集合中 {‘b’, ‘c’, ‘a’, ‘r’, ‘d’} {‘r’, ‘b’, ‘d’} {‘b’, ‘c’, ‘a’, ‘z’, ‘m’, ‘r’, ‘l’, ‘d’} {‘c’, ‘a’} {‘z’, ‘b’, ‘m’, ‘r’, ‘l’, ‘d’}


Dictionary(字典)

字典(dictionary)是Python中另一个非常有用的内置数据类型。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。

键(key)必须使用不可变类型。

在同一个字典中,键(key)必须是唯一的。

实例

#!/usr/bin/python3  
  
dict = {}  
dict['one'] = "1 - 菜鸟教程"  
dict[2]     = "2 - 菜鸟工具"  
  
tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}  
  
  
print (dict['one'])       # 输出键为 'one' 的值  
print (dict[2])           # 输出键为 2 的值  
print (tinydict)          # 输出完整的字典  
print (tinydict.keys())   # 输出所有键  
print (tinydict.values()) # 输出所有值  

以上实例输出结果:

1 - 菜鸟教程 2 - 菜鸟工具 {‘name’: ‘runoob’, ‘code’: 1, ‘site’: ‘www.runoob.com’} dict_keys([‘name’, ‘code’, ‘site’]) dict_values([‘runoob’, 1, ‘www.runoob.com’])

构造函数 dict() 可以直接从键值对序列中构建字典如下:

>>> dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)])  
{'Runoob': 1, 'Google': 2, 'Taobao': 3}  
>>> {x: x**2 for x in (2, 4, 6)}  
{2: 4, 4: 16, 6: 36}  
>>> dict(Runoob=1, Google=2, Taobao=3)  
{'Runoob': 1, 'Google': 2, 'Taobao': 3}  

{x: x**2 for x in (2, 4, 6)} 该代码使用的是字典推导式,更多推导式内容可以参考:Python 推导式

另外,字典类型也有一些内置的函数,例如 clear()、keys()、values() 等。

注意:

  • 1、字典是一种映射类型,它的元素是键值对。
  • 2、字典的关键字必须为不可变类型,且不能重复。
  • 3、创建空字典使用 { }

    批注

    最好不要把一个dict命名为dict,这种关键字居然不保留。


bytes 类型

在 Python3 中,bytes 类型表示的是不可变的二进制序列(byte sequence)。

与字符串类型不同的是,bytes 类型中的元素是整数值(0 到 255 之间的整数),而不是 Unicode 字符。

bytes 类型通常用于处理二进制数据,比如图像文件、音频文件、视频文件等等。在网络编程中,也经常使用 bytes 类型来传输二进制数据。

创建 bytes 对象的方式有多种,最常见的方式是使用 b 前缀:

此外,也可以使用 bytes() 函数将其他类型的对象转换为 bytes 类型。bytes() 函数的第一个参数是要转换的对象,第二个参数是编码方式,如果省略第二个参数,则默认使用 UTF-8 编码:

x = bytes(“hello”, encoding=”utf-8”)

与字符串类型类似,bytes 类型也支持许多操作和方法,如切片、拼接、查找、替换等等。同时,由于 bytes 类型是不可变的,因此在进行修改操作时需要创建一个新的 bytes 对象。例如:

实例

x = b"hello"  
y = x[1:3]  # 切片操作,得到 b"el"  
z = x + b"world"  # 拼接操作,得到 b"helloworld"  

需要注意的是,bytes 类型中的元素是整数值,因此在进行比较操作时需要使用相应的整数值。例如:

x = b"hello"  
if x[0] == ord("h"):  
    print("The first element is 'h'")  

其中 ord() 函数用于将字符转换为相应的整数值。


Python数据类型转换

有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可,在下一章节 Python3 数据类型转换 会具体介绍。

以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。

函数 描述
int(x [,base]) 将x转换为一个整数
float(x) 将x转换到一个浮点数
complex(real [,imag]) 创建一个复数
str(x) 将对象 x 转换为字符串
repr(x) 将对象 x 转换为表达式字符串
eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s) 将序列 s 转换为一个元组
list(s) 将序列 s 转换为一个列表
set(s) 转换为可变集合
dict(d) 创建一个字典。d 必须是一个 (key, value)元组序列。
frozenset(s) 转换为不可变集合
chr(x) 将一个整数转换为一个字符
ord(x) 将一个字符转换为它的整数值
hex(x) 将一个整数转换为一个十六进制字符串
oct(x) 将一个整数转换为一个八进制字符串

in

在 Python 3 中,关键字 in 有两个主要的用途:检查成员关系和用于迭代。以下是详细的解释和示例。

1. 检查成员关系

关键字 in 可以用来检查一个元素是否在某个集合(如列表、元组、字符串、字典、集合)中。

示例:

  • 列表
      fruits = ['apple', 'banana', 'cherry']
      if 'banana' in fruits:
          print('Banana is in the list.')
    
  • 字符串
      text = "hello world"
      if 'world' in text:
          print('Found "world" in the text.')
    
  • 字典(检查键是否存在):
      my_dict = {'name': 'Alice', 'age': 25}
      if 'name' in my_dict:
          print('Key "name" is in the dictionary.')
    
  • 集合
      my_set = {1, 2, 3, 4}
      if 3 in my_set:
          print('3 is in the set.')
    

2. 用于迭代

关键字 in 也可以在 for 循环中使用,用于迭代一个可迭代对象(如列表、元组、字符串、字典、集合等)。

示例:

  • 列表
      fruits = ['apple', 'banana', 'cherry']
      for fruit in fruits:
          print(fruit)
    
  • 字符串
      for char in "hello":
          print(char)
    
  • 字典(迭代键):
      my_dict = {'name': 'Alice', 'age': 25}
      for key in my_dict:
          print(key, my_dict[key])
    
  • 集合
      my_set = {1, 2, 3, 4}
      for item in my_set:
          print(item)
    

总结

  • 成员检查in 用于检查一个元素是否在某个集合中。
      element in collection
    
  • 迭代in 用于 for 循环中,迭代一个可迭代对象。
      for element in iterable:
          # do something with element
    

以下是一个包含两种用途的示例代码:

# 成员检查
nums = [1, 2, 3, 4, 5]
if 3 in nums:
    print("3 is in the list.")

# 用于迭代
for num in nums:
    print(num)

这个示例展示了如何使用 in 来检查成员关系以及用于迭代列表中的元素。


dot“.”运算符

在Python中,点号.运算符有几种不同的用法,这可能导致一些混淆。让我来为你解释一下:

1. 属性访问

最常见的用法是用.来访问对象的属性或方法。例如:

class MyClass:
    def __init__(self):
        self.my_attribute = 10
    
    def my_method(self):
        return "Hello"

obj = MyClass()
print(obj.my_attribute)  # 访问属性
print(obj.my_method())    # 调用方法

在这个例子中,obj.my_attributeobj.my_method()中的.用来访问obj对象的属性和方法。

2. 模块访问

.也用于访问模块中的变量、函数或子模块。例如:

import math

print(math.pi)  # 访问math模块中的pi变量
print(math.sqrt(16))  # 调用math模块中的sqrt函数

这里的.用来指示从math模块中获取pi变量和sqrt函数。

3. 文件路径

.也用于指示文件路径中的目录结构。例如:

import os

file_path = os.path.join("path", "to", "file.txt")

在这里,.用来连接文件路径的不同部分。

总之,.在Python中是一个非常常见的运算符,用于访问对象的属性和方法,访问模块的内容,以及构建文件路径。


装饰器

花哨一点的包裹方法

Python 中的装饰器(decorators)是一种设计模式,允许你在不修改已有函数或方法代码的情况下,向其添加新的功能或行为。装饰器本质上是一个函数,它接受一个函数作为输入,并返回一个新的函数。装饰器广泛应用于跨切关注点(cross-cutting concerns)如日志记录、访问控制、性能测量等方面。

基本语法

装饰器使用 @decorator_name 语法来应用于函数或方法。

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        print(f"Wrapper executed this before {original_function.__name__}")
        result = original_function(*args, **kwargs)
        print(f"Wrapper executed this after {original_function.__name__}")
        return result
    return wrapper_function

@decorator_function
def display():
    print("Display function ran")

display()

示例解释

  1. 定义装饰器函数: decorator_function 接受一个函数 original_function 作为参数,并返回一个 wrapper_function
  2. 包装函数: wrapper_function 在调用 original_function 之前和之后执行额外的代码。
  3. 应用装饰器: @decorator_function 应用于 display 函数。这相当于 display = decorator_function(display)
  4. 调用装饰函数: 调用 display() 时,实际上运行的是 wrapper_function,其中包含了 original_function 的调用。

使用多个装饰器

你可以将多个装饰器堆叠在一起使用,顺序从内到外应用。

@decorator_one
@decorator_two
def function():
    pass

相当于:

function = decorator_one(decorator_two(function))

装饰器的实际应用

  1. 日志记录:
     def log_decorator(func):
         def wrapper(*args, **kwargs):
             print(f"Calling function {func.__name__}")
             result = func(*args, **kwargs)
             print(f"Function {func.__name__} returned {result}")
             return result
         return wrapper
    
  2. 访问控制:
     def requires_authentication(func):
         def wrapper(*args, **kwargs):
             if not user.is_authenticated:
                 raise Exception("User not authenticated")
             return func(*args, **kwargs)
         return wrapper
    
  3. 性能测量:
     import time
     def timing_decorator(func):
         def wrapper(*args, **kwargs):
             start_time = time.time()
             result = func(*args, **kwargs)
             end_time = time.time()
             print(f"{func.__name__} took {end_time - start_time} seconds")
             return result
         return wrapper
    

装饰器在 Python 中是一个强大而灵活的工具,能够使代码更简洁和更易维护,同时增强其功能。


@staticmethod

在Python中,@staticmethod是一个装饰器,用来标记一个方法为静态方法。这意味着这个方法不依赖于类的实例,也就是说,它不会自动接收第一个参数self。静态方法可以通过类直接调用,而不需要创建类的实例。

使用@staticmethod装饰器的好处是,你可以在不创建类实例的情况下调用这个方法,这通常用于工具函数,这些函数既不修改类状态也不需要访问类的状态。

示例代码

下面是一个使用@staticmethod的简单示例:

class Math:
    @staticmethod
    def add(x, y):
        return x + y

# 直接通过类调用静态方法
result = Math.add(1, 2)
print(result)  # 输出 3

在这个例子中,add方法是一个静态方法,它简单地接受两个参数,计算它们的和,并返回结果。这个方法不需要访问任何关于Math类实例的数据。


lambda

在Python中,lambda 是一个用于创建匿名函数的关键字。它允许我们定义简单的、单行的函数,通常用于需要一个函数对象作为参数的场合,或者需要一个短小的函数的地方。

语法

lambda 函数的语法形式如下:

lambda arguments: expression
  • lambda:关键字,表示创建一个匿名函数。
  • arguments:函数的参数列表,类似于正常的函数参数。
  • expression:函数体,是一个表达式,定义了函数的返回值。

范例

下面是一些示例来说明 lambda 函数的用法:

  1. 简单的加法函数
    add = lambda x, y: x + y
    print(add(3, 5))  # 输出结果为 8
    
  2. 与内置函数结合使用
    numbers = [1, 2, 3, 4, 5]
    squared = list(map(lambda x: x**2, numbers))
    print(squared)  # 输出结果为 [1, 4, 9, 16, 25]
    

    在这个示例中,lambda 函数被用作 map 函数的参数,用于将列表 numbers 中的每个元素平方。

  3. 条件判断
    is_even = lambda x: x % 2 == 0
    print(is_even(4))  # 输出结果为 True
    print(is_even(5))  # 输出结果为 False
    

    在这个示例中,lambda 函数用于检查一个数字是否为偶数。

实例

这两个Python语句之间的主要区别在于 command 参数的使用方式。

  1. command=RL_model:这个语句正确地将 RL_model 函数作为按钮点击事件的回调函数。在这里,RL_model 是一个函数对象,不会立即执行。当你点击按钮时,Tkinter 会调用这个函数,因此每次点击按钮时,RL_model 都会执行一次。
  2. command=RL_model():这个语句在创建按钮的时候立即执行了 RL_model 函数,并将其返回值(如果有的话)设置为按钮的 command 参数。这意味着函数只在按钮创建时执行一次,而不是每次点击按钮时。如果 RL_model 函数没有返回一个函数,那么点击按钮时不会有任何动作发生。 所以,第一种方式是设置按钮点击回调函数的正确方法。第二种方式则在创建按钮时就执行了一次函数,之后点击按钮不会触发任何操作(除非 RL_model 返回了一个函数)。

要向 RL_model 函数传入参数并确保每次点击按钮时都能调用该函数,您可以使用一个lambda表达式来创建一个匿名函数,这个匿名函数在每次按钮被点击时都会被调用,并且它会调用 RL_model 函数并传入必要的参数。

假设您要传递一个名为 param 的参数到 RL_model 函数,您可以这样做: ttk.Button(self.control_frame, text="RL_model", command=lambda: RL_model(param)).grid(row=11, columnspan=8, padx=5, pady=5)

这里,lambda 创建了一个匿名函数,没有参数,并在每次按钮点击时调用 RL_model(param)


特点与限制

  • 匿名性lambda 函数是匿名的,意味着它们不像正常的函数那样有一个标识符来引用。
  • 单行函数lambda 函数限制在一个表达式内部,不能包含多个语句或复杂逻辑。
  • 适用范围:通常用于简单的数据转换、过滤或作为简单回调函数传递给高阶函数等场景。

由于其简洁性和便利性,lambda 函数在函数式编程风格和处理数据集合的函数式编程方法中广泛使用。


@abstractmethod

使用 @abstractmethod 抽象方法:

所在的 class 继承 abc.ABC 给需要抽象的实例方法添加装饰器 @abstractmethod 完成这两步后, 这个 class 就变成了抽象类, 不能被直接实例化, 要想使用抽象类, 必须继承该类并实现该类的所有抽象方法

示例代码:

from abc import ABC, abstractmethod


class Animal(ABC):
    @abstractmethod
    def info(self):
        print("Animal")


class Bird(Animal):
    # 实现抽象方法
    def info(self):
        # 调用基类方法(即便是抽象方法)
        super().info()
        print("Bird")


断言 assert

也就是说如果断言表达式为假,产生异常


enumerate枚举(for)

在Python中,enumerate 函数用于将一个可迭代的数据对象组合为一个索引序列,同时列出数据和数据下标。例如:

for i, output in enumerate(outputs)

这一行的逻辑如下:

  1. outputs:这个变量通常代表模型对一批测试数据所做的预测。在深度学习中,这通常是一个包含多个输出的tensor,其中每个输出是对应于输入数据点(如一张图片)的预测结果。

  2. enumerate(outputs):这个函数遍历outputs,每次迭代返回两个值:
    • i:当前迭代的索引(或位置)。在这种情况下,i 表示当前输出(预测结果)在outputs批次中的位置。
    • output:在当前迭代中的实际值,这里指的是单个预测结果。
  3. 循环体内的逻辑(尽管你没有在问题中提供,但可以基于前一个答案推断):
    • 每个output代表对应于测试数据中单个输入项的预测结果。
    • 使用torch.argmax(output)来找到预测结果中概率最高的类别的索引。这是模型对该特定输入的分类预测。
    • y[i]是该输入的真实标签,通过比较torch.argmax(output)y[i]来判断模型的预测是否准确。

例如,如果outputs是一个尺寸为[batch_size, num_classes]的tensor,其中batch_size是这批次中的样本数量,num_classes是类别的总数,则每个output都是一个长度为num_classes的tensor,表示模型对单个样本的分类预测的置信度。enumerate使得你可以同时获取每个预测的索引和预测值,这对于将预测结果与其对应的真实标签进行比较是很有用的。

这种结构允许在处理批量数据时有效地追踪每个数据点和其预测结果,是处理深度学习模型输出的常见方式。


super.init()

在Python中,super()函数用于调用父类(超类)的方法。super().__init__()这种用法尤其常见于类的构造函数中,即__init__()方法。这里是它的具体作用:

  1. 调用父类的构造函数:当你在一个子类中定义__init__()方法时,通常需要确保父类也被正确地初始化。使用super().__init__()可以确保父类的构造函数被调用,这样父类的所有属性和方法才能在子类中正常使用。

  2. 避免直接父类名的硬编码:使用super()可以避免在调用父类方法时硬编码父类的名称。这样,如果改变了类的继承关系,不需要修改每一个使用到父类方法的地方。

  3. 支持多重继承:在Python的多重继承场景中,super()按照方法解析顺序(MRO,Method Resolution Order)调用父类的方法,这保证了所有父类被适当地初始化或者调用相应的方法。 ```python class Parent: def init(self): self.value = “Inside Parent”

class Child(Parent): def init(self): super().init() # 调用Parent类的构造函数 self.child_value = “Inside Child”

创建Child类的实例

child_instance = Child() print(child_instance.value) # 输出 “Inside Parent” print(child_instance.child_value) # 输出 “Inside Child”


---
# with
在Python中,`with`语句是用于简化资源管理的一个语法结构,特别是在涉及到需要设置和清理的操作时。这通常与资源的分配和释放有关,如文件操作、网络连接或锁的管理。使用`with`语句可以确保程序部分的执行完成后,无论执行过程中发生什么(例如错误或异常),都会执行必要的“清理”操作。

### 基本用法

`with`语句通常与上下文管理器一起使用。上下文管理器是一个Python对象,它定义了在执行代码块前后应执行的操作。上下文管理器对象需要实现两个方法:`__enter__()` 和 `__exit__()`。

- `__enter__()` 方法在代码块执行之前调用,可以返回一个值(通常是资源对象),这个值可以被`with`语句绑定到一个变量。
- `__exit__(self, exc_type, exc_val, exc_tb)` 方法在代码块执行完成后调用,无论代码块正常结束还是抛出异常都会执行。它可以用来处理异常、进行清理工作或释放资源。`exc_type`, `exc_val`, 和 `exc_tb` 这三个参数用于传递异常类型、值和追踪记录。

### 示例:文件操作

一个常见的`with`语句使用场景是文件操作。在不使用`with`语句的情况下,如果在文件操作过程中发生异常,可能会导致文件没有被正确关闭,从而引发资源泄漏。使用`with`语句可以避免这种情况:

```python
with open('example.txt', 'r') as file:
    content = file.read()
    print(content)
# 文件在这里自动关闭,即使读取过程中发生异常

网络和数据库连接

with语句也常用于管理网络连接或数据库会话,确保它们在不再需要时被正确关闭:

import sqlite3

with sqlite3.connect('example.db') as conn:
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM users')
    print(cursor.fetchall())
# 数据库连接在这里自动关闭

自定义上下文管理器

你也可以创建自己的上下文管理器,通过定义一个类并实现__enter____exit__方法:

class ManagedResource:
    def __enter__(self):
        print("Acquire resource")
        return self
    
    def __exit__(self, exc_type, exc_value, traceback):
        print("Release resource")
        if exc_type:
            print(f"An error occurred: {exc_value}")
        return True  # 可以选择不向上抛出异常

with ManagedResource() as resource:
    print("Using resource")
    raise Exception("Something went wrong")  # 异常被`__exit__`处理

在这个例子中,ManagedResource类管理一个资源,它在进入with代码块时被获取,在退出时被释放,即使发生了异常。

总结

with语句通过自动处理设置和清理逻辑,使得代码更简洁、更安全。它尤其适合用于需要确保资源释放的场合,如文件读写、网络通信和数据库交云。


for神奇用法

这行代码:

dp = [[0] * (n + 1) for _ in range(m + 1)]

是用来初始化一个二维数组(列表)的操作。具体来说,这段代码做了以下事情:

  1. 创建一个二维数组(列表)dp:
    • dp 是一个大小为 (m+1) x (n+1) 的二维数组,其中 m 是数组 nums1 的长度,n 是数组 nums2 的长度。
    • 这个二维数组的每个元素初始值都设为 0
  2. 理解 [[0] * (n + 1) for _ in range(m + 1)]:
    • [0] * (n + 1) 生成了一个包含 n+10 的列表。这意味着每一行都会有 n+1 个元素,初始值都为 0
    • for _ in range(m + 1) 是一个循环,它会执行 m+1 次。每次循环都会创建一个新的列表(相当于二维数组的一行)。
    • 最终,这段代码生成一个二维数组 dp,它有 m+1 行和 n+1 列,并且所有元素的初始值都是 0

假设 m = 2n = 3,则 dp 的初始化如下:

dp = [
    [0, 0, 0, 0],  # 第1行
    [0, 0, 0, 0],  # 第2行
    [0, 0, 0, 0]   # 第3行
]

每一行都有 n+10,总共有 m+1 行。这个二维数组将用于存储动态规划的中间结果。


map()

描述

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

语法

map() 函数语法:

map(function, iterable, ...)

参数

  • function – 函数
  • iterable – 一个或多个序列

返回值

Python 2.x 返回列表。

Python 3.x 返回迭代器。

Python3.x 实例

>>> def square(x) :         # 计算平方数  
...     return x ** 2  
...  
>>> map(square, [1,2,3,4,5])    # 计算列表各个元素的平方  
<map object at 0x100d3d550>     # 返回迭代器  
>>> list(map(square, [1,2,3,4,5]))   # 使用 list() 转换为列表  
[1, 4, 9, 16, 25]  
>>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))   # 使用 lambda 匿名函数  
[1, 4, 9, 16, 25]  
>>>