栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 基础

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 基础

文章目录
  • Python 语法
    • 注释
    • 标识符
    • 关键字
    • 变量的赋值
    • 代码规范
  • 标准数据类型
    • Number 类型
      • 数字函数
    • String 类型
      • 转义符
      • 格式化字符串
      • f-string
      • format()
      • 字符串方法
    • List
      • 列表方法
      • 列表推导式
    • Tuple
    • Set
      • 集合方法
    • Dictionary
    • 字典方法
    • 函数
    • 数据类型转换
    • 其他操作
  • 运算符
    • 算术运算符
    • 比较(关系)运算符
    • 赋值运算符
    • 位运算符
    • 逻辑运算符
    • 成员运算符
    • 身份运算符
    • 运算符优先级
  • if 条件控制
  • 循环语句
    • while 条件循环
    • for 循环遍历
      • 遍历技巧
    • break and continue
    • pass 语句
  • 迭代器与生成器
    • 迭代器
      • 创建迭代器
      • 迭代结束标志
    • 生成器
  • 函数
    • 参数
    • 匿名函数
  • 模块
    • import 语句
    • from ... import 语句
    • __name__ 属性
    • dir() 函数
  • 输入输出
    • 标准输出
    • 标准输入
    • 读写文件


Python 语法 注释

Python 的注释风格:

# 行注释

'''
块注释1
'''

"""
块注释2
"""

注释中的内容将不会被执行。


标识符
  • 首字母必须是大写或小写的英文字母或者下划线 _。
  • 其他部分由大写或小写的英文字母、数字和下划线组成。
  • 大小写敏感(区分大小写)。

Python3 中允许使用非 ASCII 标识符,即中文也可作为标识符:

>>> 变量 = 5
>>> print(变量)
5

关键字

Python 关键字(keyword)不能作为标识符使用,关键字又称保留字。

使用 keyword 模块输出 Python 的所有关键字:

>>> import keyword
>>> print(keyword.kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

变量的赋值

Python 中的变量并不需要声明,直接赋值后就可使用。还可以同时为多个变量赋值。

pai, e = 3.14, 2.72
a = b = c = 1

代码规范

Python 代码中的所有块都是使用空格缩进来表示。同一块中的所有语句都必须包含相同的缩进空格数,一般使用 4 个空格作为缩进,并且最好在代码编辑器中设置将 Tab 转化为空格。

total = 0
# 输出数字 1~9 的平方数
for n in range(1, 10):
    # 块的开始
    square = n * n
    total += square
    print(square)
	# 块的结束
# 输出数字 1~9 的所有平方数的总和
print(total)

缩进相同的一组语句构成一个代码块,或称之为代码组。


函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。

空行是程序代码的一部分,但并不是 Python 语法的一部分。空行的作用在于分割两段不同功能或含义的代码,便于日后代码的维护或重构,有无空行并不影响程序运行。


反斜杠 作为续行符,表示下一行是上一行的延续。对于过长的语句,Python 使用反斜杠、换行再加上缩进来将长语句分为多行。

total = item_one + 
        item_two + 
        item_three

在 [],{}, 或 () 中的多行语句,不需要使用反斜杠 来换行。

total = ['item_one', 'item_two', 'item_three',
        'item_four', 'item_five']

Python 可以在同一行中使用多条语句,语句之间使用分号 ; 分割。

>>> str = '123'; print(str)
123

标准数据类型

Python 支持 6 种基本数据类型:

  • Number —— 数字类型
  • String —— 字符串类型
  • List —— 列表
  • Tuple —— 元组
  • Set —— 集合
  • Dictionary —— 字典

List、Dictionary、Set 是 Python 内置的数据结构。

Python 变量分为可变和不可变数据类型,以下是它们的定义:

  • 不可变(immutable)数据类型:当该数据类型对应的变量的值发生了改变,它对应的内存地址也会发生改变(重新分配内存空间),如 Number、String、Tuple。即,数据中的元素不能被更改。

    # 测试 Number 类型是否是不可变数据类型
    n = 1			# 赋值
    print(id(n), type(n))
    
    n = 2			# 改变值
    print(id(n), type(n))
    
    # 可能输出:
    # 1562536992 
    # 1562537024 
    
  • 可变(mutable)数据类型:当该数据类型对应的变量的值发生了改变,它对应的内存地址不发生改变,如 List、Dictionary、Set。即,数据中的元素可以被更改。

可迭代对象:List、Tuple、Set 、 Dictionary 和 String。


Number 类型

Python 支持的数字类型:

  • int —— 整数类型。
  • float —— 浮点数类型(实数类型),如 3.14、3E-2。
  • bool —— 布尔类型(True 和 False)。
  • complex —— 复数类型,如 1.1 + 2.2j、complex(a, b)。

Python 2 中有 long 型,Python 3 中没有。


数字函数

数字函数需要导入 math 模块:import math

函数描述
abs(x)返回数字 x(可以是复数)的绝对值(内置函数,不用导入 math 模块)。
ceil(x)返回数字 x 的上入整数(向上取整)。
cmp(x, y)如果 x < y 返回 -1,如果 x == y 返回 0,如果 x > y 返回 1。
Python 3 已废弃,使用 (x>y)-(x
exp(x)返回 e 的 x 次幂 e x e^x ex。
fabs(x)返回数字 x(不能是复数)的绝对值。
floor(x)返回数字的下舍整数(向下取整)。
log(x[, y])log(x) —— 返回 x 的自然对数;
log(x, y) —— 返回以 y 为基数的 x 的对数: log ⁡ y x log_y{x} logy​x。
log10(x)返回以 10为基数的 x 的对数。
max(x1, x2,...)返回给定参数的最大值,参数可以为序列。
min(x1, x2,...)返回给定参数的最小值,参数可以为序列。
modf(x)返回 x 的整数部分与小数部分,两部分的数值符号与 x 相同,整数部分以浮点型表示。
pow(x, y[, z])pow(x, y) —— x**y 运算后的值;
pow(x, y, z) —— 相当于 pow(x, y) % z。
通过内置方法调用,会把参数作为整型,而 math 会把参数转换为 float。
round(x [, n])返回浮点数 x 的四舍五入值,
如给出 n 值,则代表舍入到小数点后的位数。
其实准确的说是保留值将保留到离上一位更近的一端。
sqrt(x)返回数字 x 的平方根。

String 类型

Python 的字符串(String)有以下特点:

  • 字符串常量可以使用单引号 ' 和双引号 " 指定。

    >>> str1 = 'Hello'
    >>> str2 = 'World'
    >>> print(str1, str2, '!')
    Hello World !
    >>> str1 = '打印 "双引号" '
    >>> str1 += "要用 '单引号' 将其括起来"
    >>> print(str1)
    打印 "双引号" 要用 '单引号' 将其括起来
    
  • 使用三个引号可指定一个多行字符串常量。

    >>> str1 = """这是一个段落,
    ... 可以由多行组成"""
    >>> print(str1)
    这是一个段落,
    可以由多行组成
    
  • 转义符用 开头。单个反斜杠依然可以作为续行符。

    >>> str = 'str
    ... ing'
    >>> print(str)
    string
    
  • 使用 r 或 R 可以让反斜杠不发生转义。这样的字符串被称为原始字符串。

    >>> print(r"this is a line with n")
    this is a line with n
    
  • 按字面意义级联字符串。

    >>> print('this ' 'is ' 'string')
    this is string
    
  • 字符串可以用 + 运算符连接在一起,用 * 运算符重复。

    >>> print('this ' + 'is ' + 'string')
    this is string
    >>> str = 'Hello World!' * 3
    >>> print(str)
    Hello World!Hello World!Hello World!
    
  • 有两种索引方式:从左往右以 0 开始,从右往左以 -1 开始。

  • 字符串的截取的语法格式:变量[头下标:尾下标:步长]。字符串被截取后返回一个包含所需字符的新字符串。遵循左闭右开原则。

    尾下标从 1 开始。

    步长是指输出字符串中第 n n n 个字符后,接着输出第 ( n + 步 长 ) (n + 步长) (n+步长) 个字符,直至到达尾下标指定处。

    省略步长代表按字符串顺序输出,省略尾下标代表截取到字符串的最后一个字符,省略头下标代表从第一个字符开始截取。

    >>> str='123456789'
    >>> print(str[0])		# 输出字符串第一个字符
    1
    >>> print(str[2:5])		# 输出从第三个开始到第五个的字符
    345
    >>> print(str[0:-1])	# 输出第一个到倒数第二个的所有字符
    12345678
    >>> print(str[2:])		# 输出从第三个开始后的所有字符
    3456789
    >>> print(str[:3])		# 输出从第一个开始到第三个的字符
    123
    >>> print(str[1:5:2])	# 输出从第二个开始到第五个且每隔一个的字符(步长为2)
    24
    >>> print(str[:])		# 同时省略头下标和尾,创建了一个str的副本
    
  • 字符串不能改变。即,字符串的切片不能被赋值。

    >>> str = 'string'
    >>> str[0] = 'S'
    Traceback (most recent call last):
      File "", line 1, in 
    TypeError: 'str' object does not support item assignment
    >>> str = 'string'
    >>> print(str)
    string
    >>> str = 'String'	# 修改字符串只能重新进行赋值
    >>> print(str)
    String
    
  • Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。

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

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


转义符
转义字符描述
(在代码行尾时)续行符。
\反斜杠符号。
'单引号。
"双引号。
a响铃
print("a")执行后电脑有响声。
b退格(Backspace)。
00空。
n换行。
v纵向制表符。
t横向制表符。
r回车,将 r 后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将 r 后面的内容完全替换完成。
f换页。
yyy八进制数,y 代表 0~7 的字符,如 12 代表换行。
xyy十六进制数,以 x 开头,y 代表的字符,例 x0a 代表换行。
other其它的字符以普通格式输出。

格式化字符串

print() 函数能够使用 % 来进行格式化字符串的输出。例如:

>>> print('%e' % 3.14)
3.140000e+00

字符串格式化符号:

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

格式化操作符辅助符号:

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

辅助符号在格式字符串 % 和符号中间使用,如需指定其它参数需要在字符串后的 % 使用括号 () 指定参数和要显示的值。如:

>>> print('%*d' % (10, 2))
         2

f-string

f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。f-string格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去。

>>> name = 'World!'
>>> f'Hello {name}'  # 替换变量
'Hello World!'
>>> f'{1+2}'         # 使用表达式
'3'

format()

str.format() 是用于格式化字符串的字符串方法。

format() 将 str 中的格式化字段({} 及其里面包含的字符)替换为 format() 中的参数。它的用法如下:

>>> print('{} and {}'.format('a', 'b'))			# 按照参数顺序
a and b
>>> print('{1} and {0}'.format('a', 'b'))		# 指定参数位置(从 0 开始)
b and a
>>> print('{} and {b}'.format('a', b = 'b'))	# 指定关键字
a and b

!a(使用 ascii()),!s(使用 str())和 !r(使用 repr())可以用于在格式化某个值之前对其进行转化:

>>> import math
>>> print('常量 PI 的值近似为: {}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。
>>> print('常量 PI 的值近似为: {!r}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。

可以使用 :,在右边指定输出形式,在 : 左边的是 format() 参数位置:

>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142。

在 : 后传入一个整数, 可以保证该域至少有这么多的宽度。

>>> table = {'a': 1, 'b': 2, 'c': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
...
a          ==>          1
b          ==>          2
c          ==>          3

传入一个字典,然后使用方括号 [] 来访问键值:

>>> table = {'a': 1, 'b': 2, 'c': 3}
>>> print('b: {0[b]:d}; a: {0[a]:d}; c: {0[c]:d}'.format(table))
b: 2; a: 1; c: 3

也可以通过在变量前使用 ** 来实现相同的功能:

>>> table = {'a': 1, 'b': 2, 'c': 3}
>>> print('b: {b:d}; a: {a:d}; c: {c:d}'.format(**table))
b: 2; a: 1; c: 3

字符串方法
方法说明
str.capitalize()将字符串的第一个字符转换为大写。
str.center(width[, fillchar])返回一个指定的宽度 width 居中的字符串。
fillchar 为填充的字符,默认为空格。
str.count(sub[, start= 0, end=len(string)])返回 sub 在 str 的指定范围里面出现的次数。
sub —— 搜索的子字符串。
start —— 字符串开始搜索的位置。默认为第一个字符(索引为 0)。
end —— 字符串中结束搜索的位置。默认为字符串的最后一个位置。
str.encode(encoding='UTF-8',errors='strict')以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是 'ignore' 或者 'replace'。
bytes.decode(encoding="utf-8", errors="strict")以指定的编码格式解码 bytes 对象。
encoding —— 要使用的编码,默认为 "utf-8"。
errors —— 设置不同错误的处理方案。默认为 "strict",意为编码错误引起一个 UnicodeError。 其他可能的值有 "ignore","replace","xmlcharrefreplace","backslashreplace" 以及通过 codecs.register_error() 注册的任何值。
Python3 中没有 decode() 方法,但可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回↩️。
str.endswith(suffix[, start=0, end=len(string)])检查字符串指定范围是否以 suffix 结束,如果是,返回 True,否则返回 False。
suffix —— 可以是一个字符串或者是一个元素。
start —— 指定的开始位置。默认为字符串第一个字符(索引为 0)。
end —— 指定的结束位置。默认为字符串的最后一个字符。
str.expandtabs(tabsize=8)把字符串 str 中的 Tab 符号 t 转为空格。
tabsize —— Tab 符号的长度,默认为 8。
str.find(sub[, beg=0, end=len(str)])检测 sub 是否包含在字符串 str 的指定范围中,如果包含则返回开始的索引值,否则返回 -1。
sub —— 字符串。
beg —— 指定的开始位置。默认为字符串第一个字符(索引为 0)。
end —— 指定的结束位置。默认为字符串的最后一个字符。
str.index(sub[, beg=0, end=len(string)])同 find()方法一样,只不过如果 sub 不在字符串中会报一个异常。
str.isalnum()如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False。
str.isalpha()如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False。
str.isdigit()如果字符串只包含数字则返回 True,否则返回 False。
str.islower()如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False。
str.isnumeric()如果字符串中只包含数字字符,则返回 True,否则返回 False。
str.isspace()如果字符串中只包含空白,则返回 True,否则返回 False。
str.istitle()如果字符串是标题化的(见 title()),则返回 True,否则返回 False。
str.isupper()如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False。
str.join(sequence)字符串 str 作为分隔符,将 sequence 中所有的元素(的字符串表示)合并为一个新的字符串。
len(string)返回字符串长度。
str.ljust(width[, fillchar])返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。如果指定的长度小于原字符串的长度则返回原字符串。
str.lower()转换字符串中所有大写字符为小写。
str.lstrip([chars])截掉字符串左边的空格或指定字符。
chars —— 指定截取的字符。
str.maketrans(intab, outtab)创建字符映射的转换表。↩️
intab —— 字符串,表示需要转换的字符。
outtab —— 字符串表示转换的目标。
max(str)返回字符串 str 中最大的字母。
min(str)返回字符串 str 中最小的字母。
str.replace(old, new[, max])将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
str.rfind(sub[, beg=0,end=len(string)])类似于 find() 函数,不过是从右边开始查找。即,返回字符串最后一次出现的位置,如果没有匹配项则返回 -1。
str.rindex(sub[, beg=0, end=len(string)])类似于 index(),不过是从右边开始。即,返回子字符串 sub 在字符串中最后出现的位置,如果没有匹配的字符串会报异常。
str.rjust(width[, fillchar])返回一个原字符串右对齐,并使用 fillchar(默认空格)填充至长度 width 的新字符串。
str.rstrip([chars])删除字符串末尾的指定字符 chars,默认为空格。
str.split([str1="", num=string.count(str1)])以参数 str1 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串↩️。
str.splitlines([keepends])按照行('r','rn',n')分隔,返回一个包含各行作为元素的列表。如果参数 keepends 为 False,返回的列表则不包含换行符;如果为 True,则保留换行符。
str.startswith(substr[, beg=0, end=len(string)])检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果 beg 和 end 指定值,则在指定范围内检查。
str.strip([chars])在字符串上执行 lstrip() 和 rstrip()。即移除字符串头尾指定的字符 chars(默认为空格)。
str.swapcase()将字符串中大写转换为小写,小写转换为大写。
str.title()返回 “标题化” 的字符串,即转化为所有单词都是以大写开始,其余字母均为小写的形式。
str.translate(table[, deletechars=""])根据 str 给出的表(包含 256 个字符)转换 str 的字符,要过滤掉的字符放到 deletechars 参数中。
str.upper()转换字符串中的小写字母为大写。
str.zfill (width)返回长度为 width 的字符串,原字符串右对齐,前面填充 0。
str.isdecimal()检查字符串是否只包含十进制字符(只存在于 unicode 对象。),如果是返回 True,否则返回 False。

encode() 和 decode() 用法实例:

>>> str = "Hello World!";
>>> str_utf8 = str.encode("UTF-8")
>>> str_gbk = str.encode("GBK")
>>> print(str)
Hello World!
>>> print("UTF-8 编码:", str_utf8)
UTF-8 编码: b'Hello World!'
>>> print("GBK 编码:", str_gbk)
GBK 编码: b'Hello World!'
>>> print("UTF-8 解码:", str_utf8.decode('UTF-8','strict'))
UTF-8 解码: Hello World!
>>> print("GBK 解码:", str_gbk.decode('GBK','strict'))
GBK 解码: Hello World!

maketrans() 的用法:

>>> intab = "aeiou"
>>> outtab = "12345"
>>> trantab = str.maketrans(intab, outtab)
>>> str = "this is string example....wow!!!"
>>> print (str.translate(trantab))
th3s 3s str3ng 2x1mpl2....w4w!!!

split() 的用法:

>>> str = "this is string example....wow!!!"
>>> print (str.split( ))       # 以空格为分隔符
['this', 'is', 'string', 'example....wow!!!']
>>> print (str.split('i',1))   # 以 i 为分隔符
['th', 's is string example....wow!!!']
>>> print (str.split('w'))     # 以 w 为分隔符
['this is string example....', 'o', '!!!']

List

列表(List)由一系列按特定顺序排列的元素组成,它是写在方括号 [] 之间、用逗号分隔开的元素列表。列表其实更像是 Python 中的线性数据结构的实现,它具有绝大多数常见的线性数据结构的操作。

  • 列表中元素的类型可以不相同,它支持数字,字符串,甚至可以包含列表(嵌套)。

    >>> list = [1, '2', 3.4, [5, 6], (7, 8), {9, 10}]
    >>> print(list)
    [1, '2', 3.4, [5, 6], (7, 8), {9, 10}]
    
  • 有两种索引方式:从左往右以 0 开始,从右往左以 -1 开始。

  • 列表的截取的语法格式:变量[头下标:尾下标:步长]。遵循左闭右开原则。

    尾下标从 1 开始。

    步长是指输出字符串中第 n n n 个元素后,接着输出第 ( n + 步 长 ) (n + 步长) (n+步长) 个元素,直至到达尾下标指定处。

    省略尾下标代表截取到字符串的最后一个字符,省略头下标代表从第一个字符开始截取。

    >>> list = [1, '2', 3.4, [5, 6], (7, 8), {9, 10}]
    >>> print (list[0])				# 输出列表第一个元素
    1
    >>> print (list[1:3])			# 从第二个开始输出到第三个元素
    ['2', 3.4]
    >>> print (list[2:])			# 输出从第三个元素开始的所有元素
    [3.4, [5, 6], (7, 8), {9, 10}]
    >>> print(list[:])				# 同时省略头下标和尾,创建了一个list的副本
    >>> tinylist = [123, 'list']
    >>> print (list + tinylist)		# 连接列表
    [1, '2', 3.4, [5, 6], (7, 8), {9, 10}, 123, 'list']
    >>> double = tinylist * 2		# 重复列表
    >>> print(double)
    [123, 'list', 123, 'list']
    >>> print(list[::-1])			# 步长为-1,表示逆向
    [{9, 10}, (7, 8), [5, 6], 3.4, '2', 1]
    >>> list[len(list):] = [6]		# 在列表末尾插入元素
    >>> print(list)
    [1, '2', 3.4, [5, 6], (7, 8), {9, 10}, 6]
    
  • 列表中的元素是可更改的,并且列表长度也是可改变的。List 内置了许多方法来支持这种特性。

    >>> list = [1, 2, 3]
    >>> list[1] = 6
    >>> print(list)
    [1, 6, 3]
    
  • 列表可以用 + 运算符拼接,用 * 运算符重复。

    >>> list1 = [1, 2, 3]
    >>> list2 = [4, 5, 6]
    >>> list = list1 + list2
    >>> print(list)
    [1, 2, 3, 4, 5, 6]
    >>> list = list1 * 2
    >>> print(list)
    [1, 2, 3, 1, 2, 3]
    

虽然列表和字符串有一些特性很相似,但它们是两个完全不同的类型。

删除列表或列表元素:

>>> list = [1, 2, 3]
>>> del list[3]
>>> print(list)
[1, 2, 3]

列表方法
方法说明
list.append(obj)在列表末尾添加新的对象 obj,无返回值。相当于 list[len(list):] = [x]
list.count(obj)返回 obj 在列表中出现的次数。
list.extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。
seq —— 元素列表,可以是列表、元组、集合、字典,若为字典,则仅会将键(key)作为元素依次添加至原列表的末尾。
list.index(x[, start[, end]])从列表中找出某个值第一个匹配项的索引位置。如果没有找到对象则抛出异常。
x—— 查找的对象;
start —— 可选,查找的起始位置;
end —— 可选,查找的结束位置。
list.insert(index, obj)将对象插入列表,无返回值。
index —— 对象 obj 需要插入的索引位置;
obj —— 要插入列表中的对象。
list.pop([index=-1])移除列表中 index 指定的元素(默认最后一个元素),并且返回该元素的值。
list.remove(obj)移除列表中值与 obj 相同的第一个匹配项,无返回值。
list.reverse()反向列表中元素。
list.sort(key=None, reverse=False)对原列表进行排序。
key —— 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序;↩️
reverse —— 排序规则,reverse = True 降序, reverse = False 升序(默认)。
list.clear()清空列表,类似于 del list[:]。
list.copy()返回复制后的新列表,类似于 list[:]。

list.sort() 指定排序元素:

# 获取列表的第二个元素
def takeSecond(elem):
    return elem[1]

# 列表
random = [(2, 2), (3, 4), (4, 1), (1, 3)]
 
# 指定第二个元素排序
random.sort(key=takeSecond)
 
# 输出类别
print ('排序列表:', random)

# 输出:排序列表:[(4, 1), (2, 2), (1, 3), (3, 4)]

Python 列表的特性可以很方便地将其封装成其他线性数据结构。


列表推导式

列表推导式是指在方括号 [] 中使用 for 语句生成一串序列,这个 for 语句可以有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [str(round(355/113, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

Tuple

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

  • 元素的类型可以不相同。

  • 元组中只包含一个元素时,需要在元素后面添加逗号 , ,否则括号会被当作运算符使用。

  • 有两种索引方式:从左往右以 0 开始,从右往左以 -1 开始。

  • 列表的截取的语法格式:变量[头下标:尾下标:步长]。遵循左闭右开原则。

  • 元组元素不可修改是指元组中每个元素的指向永远不变。

    无法对元组的元素进行增删操作,但并非所有类型的元素都不可修改。

    • 对于不可变数据类型的元素,的确不能修改。

    • 对于可变数据类型的元素,可以按照其规则修改。

      >>> tuple = (1, [1, 2, 3])
      >>> print(tuple)
      (1, [1, 2, 3])
      >>> tuple[1][0] = 2
      >>> print(tuple)
      (1, [2, 2, 3])
      
  • 可以用 + 运算符拼接,用 * 运算符重复。

元组的某些操作可以参照列表,除了增加和删除元素的操作。


元组支持推导式:

>>> tuple(x**2 for x in range(10))
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

Set

集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。集合的基本功能是进行成员关系测试和删除重复元素。可以使用大括号 {} 或者构造函数 set() 创建集合。

  • 集合是一个无序不重复元素的集。

  • 元素的类型可以不相同。

  • 元素是可更改的。

  • 创建空集:

    使用不带参数的构造函数 set() 创建,不可使用 {} 创建({} 代表空字典)。

    >>> s = set()
    >>> print(s)
    set()
    
  • 不包含多余的重复元素。在集合中,不会多次出现的相同元素。

  • 不可使用索引或截取等操作。

  • 可以使用集合运算。

    >>> set1 = {1, 2, 3, 4, 5, 7}
    >>> set2 = {2, 4, 6, 7, 8}
    >>> print(set1 - set2)			# set1 和 set2 的差集
    {1, 3, 5}
    >>> print(set1 | set2)			# set1 和 set2 的并集
    {1, 2, 3, 4, 5, 6, 7, 8}
    >>> print(set1 & set2)			# set1 和 set2 的交集
    {2, 4, 7}
    >>> print(set1 ^ set2)			# set1 和 set2 的对称差集
    {1, 3, 5, 6, 8}
    

集合支持推导式:

>>> {x**2 for x in range(10)}
{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}

集合的成员测试:

avengers = {'captain america', 'iron man',
            'thor', 'doctor strange', 'star-Lord',
           	'hulk', 'black widow', 'black panther',
           	'spider man'}

if 'spider man' in avengers:
    print('蜘蛛侠是复仇者')
else:
    print('蜘蛛侠不是复仇者')
if 'thanos' in avengers:
    print('灭霸是复仇者')
else:
    print('灭霸不是复仇者')

集合方法
方法描述
set.add()为集合添加元素。
set.clear()移除集合中的所有元素。
set.copy()拷贝一个集合。
set.difference(set1, set2, ...)返回集合 ( s e t − s e t 1 ) ∩ ( s e t − s e t 2 ) ∩ ⋯ (set - set1)cap(set - set2)capcdots (set−set1)∩(set−set2)∩⋯。
set.difference_update(set1, set2, ...)移除集合 set 中的元素,该元素在指定的集合 set1, set2, ... 也存在。
即,将集合 set 更新为集合 ( s e t − s e t 1 ) ∩ ( s e t − s e t 2 ) ∩ ⋯ (set - set1)cap(set - set2)capcdots (set−set1)∩(set−set2)∩⋯。
set.discard(value)删除集合 set 中指定的元素 value。
与 remove() 不同的是,如果 value 不存在 set 中,并不会发生错误。
set.intersection(set1, set2, ...)返回集合 s e t ∩ s e t 1 ∩ s e t 2 ∩ ⋯ set cap set1 cap set2 cap cdots set∩set1∩set2∩⋯。
set.intersection_update(set1, set2, ...)将集合 set 更新为集合 s e t ∩ s e t 1 ∩ s e t 2 ∩ ⋯ set cap set1 cap set2 cap cdots set∩set1∩set2∩⋯。
set1.isdisjoint(set2)判断集合 set1 和 set2 是否包含相同的元素,如果没有返回 True,否则返回 False。
set1.issubset(set2)判断集合 set1 是否是集合 set2 的子集。如果是,则返回 True;否则返回 False。
set1.issuperset(set2)判断集合 set1 是否是集合 set2 的父集。如果是,则返回 True;否则返回 False。
set.pop()随机移除元素,并返回该元素。
set.remove(item)移除指定元素 item。如果 item 不存在 set 中,会发生错误。
set1.symmetric_difference(set2)返回集合 set1 和 set2 的对称差集 s e t 1 ⊕ s e t 2 set1 oplus set2 set1⊕set2。
set1.symmetric_difference_update(set2)将集合 set1 更新为 s e t 1 ⊕ s e t 2 set1 oplus set2 set1⊕set2。
set.union(set1, set2...)返回集合 s e t ∪ s e t 1 ∪ s e t 2 ∪ ⋯ set cup set1 cup set2 cup cdots set∪set1∪set2∪⋯。
set.update(added_set)添加新的元素或集合到当前集合中。
added_set —— 可以是元素或集合。

Dictionary

字典是一种映射类型,用 {} 标识,是一个无序的 key:value (键 - 值对)的集合。字典当中的元素是通过键来存取的,而不是通过偏移存取。字典还可以使用构造函数 dict() 创建。

# 一般方法:
dic = {
    'name':   'tom',
    'age':    20,
    'height': 185,    # cm
    'weight': 71      # kg
}
print(dic)
# 输出:{'name': 'tom', 'age': 20, 'height': 185, 'weight': 71}

# 构造函数:
# 1.
dic = dict(
    name =   'lucy',
    age =    18,
    height = 169,
    weight = 56
)
print(dic)
# 输出:{'name': 'lucy', 'age': 18, 'height': 169, 'weight': 56}
# 2.
dic = dict([
    ('name', 'jiessie'),
    ('age', 25),
    ('height', 178),
    ('weight', 63)
])
print(dic)
# 输出:{'name': 'jiessie', 'age': 25, 'height': 178, 'weight': 63}

# 使用 for 循环:
dic = {
    x: x**2 for x in (2, 4, 6)
}
print(dic)
# 输出:{2: 4, 4: 16, 6: 36}

更多构造字典的方法↩️。

  • 键(key)必须使用不可变类型,且是唯一的。

    >>> dic = {1:20, 'a':50, (1, 2, 3):6}
    >>> print(dic)
    {1: 20, 'a': 50, (1, 2, 3): 6}
    >>> print(dic[1])
    20
    >>> print(dic['a'])
    50
    >>> print(dic[(1, 2, 3)])
    6
    
  • 值(value)可以是任何类型的元素。

  • 使用键作为索引。

  • 使用 in 操作符判断键是否存在字典中,如 key in dict ,如果键在字典dict里返回 True,否则返回 False。not in 操作符与 in 相反。


字典方法
方法说明
radiansdict.clear()删除字典内所有元素,无返回值。
radiansdict.copy()返回一个字典的浅复制。
radiansdict.fromkeys(seq[, value])创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值(可选)。
radiansdict.get(key, default=None)返回指定键 key 的值,如果键不在字典中返回 default 设置的默认值。
radiansdict.items()以列表返回一个视图对象,视图对象中的元素以键-值对 (key, value) 的形式显示。
视图对象不是列表,不支持索引,其中的元素是键-值对。字典的视图对象都是只读的,但字典改变,视图也会跟着变化。
radiansdict.keys()返回一个只包含键的视图对象。
radiansdict.setdefault(key, default=None)和 get() 类似,如果 key 存在于 radiandict 中,就返回其值;但如果 key 不存在于字典中,将会添加键并将值设为 default。
radiansdict.update(dict2)把字典 dict2 的键-值对更新到 dict 里,无返回值。
radiansdict.values()返回一个只包含值的视图对象。
radiansdict.pop(key[, default])删除字典给定键 key 所对应的值,返回值为被删除的值。key 值必须给出。否则,返回 default 值。如果 key 不存在字典中,返回 default 值(default 值必须给出,否则会报错。
radiansdict.popitem()随机返回并删除字典中的最后一对键和值 (key, value)。
如果字典已经为空,却调用了此方法,就报出 KeyError 异常。

函数
函数说明
len(obj)返回对象的元素个数
max(x1[, x2[, x3[, ...]]])返回参数中最大值,参数还可以是集合、列表或元组。
min(x1[, x2[, x3[, ...]]])返回参数中最小值,参数还可以是集合、列表或元组。

数据类型转换

将数据类型作为函数名即可进行数据类型的转换。以下内置的数据类型转换函数返回一个新的对象,表示转换的值。

函数描述
int(x, base = 10)将 x 转换为一个整数。
x —— 字符串或数字;
base —— 基数(进制数),默认 10。
float(x = 0.0)将 x 转换为一个浮点数。
x —— 字符串或数字,默认为 0.0。
complex(real[, imag])创建一个值为 real + imag * j 的复数。
real —— 为字符串时不需要指定第二个参数,还可以为 int 或 float;
imag —— int、float。
str(object = '')将对象 object 转换为字符串,默认为空字符串。
repr(object)将对象 object 转换为表达式字符串。↩️
eval(expression[, globals[, locals]])用来执行字符串中的有效表达式,并返回表达式的值。
expression —— 表达式字符串;
globals —— 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象;
locals —— 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
tuple(iterable)将序列 iterable 转换为一个元组。
iterable —— 可迭代对象,如列表、字典、元组等等。
list(seq)将序列 seq 转换为一个列表。
seq —— 元组或字符串。
set([iterable])将 iterable 转换为可变集合,默认创建空集。
iterable —— 可迭代对象。
dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
创建一个字典,默认创建空集。↩️
**kwargs —— 关键字,如 key=value;
mapping —— 元素的容器;
iterable —— 可迭代对象。
frozenset([iterable])将 iterable 转换为不可变集合,默认创建空集。
iterable —— 可迭代的对象。
chr(i)将一个整数 i(in rang(256))转换为一个字符。
返回值是当前整数对应的 ASCII 字符。
ord(c)将一个字符 c 转换为它的整数值(ASCII 数值,或者 Unicode 数值)。
c —— 字符(长度为 1 的字符串)。
如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
hex(x)将整数 x 转换为一个十六进制字符串(以 0x 为前缀)。
oct(x)将整数 x 转换为一个八进制字符串。
Python2.x 版本的 8 进制以 0 作为前缀表示;
Python3.x 版本的 8 进制以 0o 作为前缀表示。

repr 的用法:

>>> dic = [1, 2, 3]
>>> repr(dic)
'[1, 2, 3]'

dict() 的用法:

>>>dict()                         # 创建空字典
{}
>>> dict(a='a', b='b', t='t')     # 传入关键字
{'a': 'a', 'b': 'b', 't': 't'}
>>> dict(zip(['one', 'two', 'three'], [1, 2, 3]))   # 映射函数方式来构造字典
{'one': 1, 'two': 2, 'three': 3}
>>> dict([('one', 1), ('two', 2), ('three', 3)])    # 可迭代对象方式来构造字典
{'one': 1, 'two': 2, 'three': 3}

其他操作

使用 Python 的 type() 函数查看变量的类型:

>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
   

使用 isinstance 判断数据类型是否正确:

>>> a = 111
>>> isinstance(a, int)
True

isinstance() 和 type() 的区别在于:

  • type() 不会认为子类是一种父类类型。
  • isinstance() 会认为子类是一种父类类型。即,子类和父类被认为是同一类型。
>>> class A:
...     pass
... 
>>> # B 是 A 的子类
>>> class B(A):
...     pass
... 
>>> isinstance(A(), A)
True
>>> type(A()) == A 
True
>>> isinstance(B(), A)
True
>>> type(B()) == A
False

Python3 中,bool 是 int 的子类,True 和 False 可以和数字相加。

>>> True == 1
True
>>> False == 0
True

可以通过 is 来判断:

>>> True is 1
False
>>> flag = True
>>> flag is True
True

使用 del 删除对象:

del var				# 删除一个对象
del var_1, var_2	# 删除多个对象

print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":

>>> str1 = 'Hello '
>>> str2 = 'World!'
>>> print(str1); print(str2)
Hello
World!
>>> print(str1, end = ''); print(str2)
Hello World!

运算符 算术运算符
OperatorsExplains
+
操作对象为字符串、列表或元组时,表示将两个对象拼接在一起。
-
*
a * b,若 a 为字符串、列表或元组,b 为整数时,表示将 b 个 a 拼接在一起。
/
%取模
**幂,如 a**b 返回 a 的 b 次方
//整除,向下取整

比较(关系)运算符

所有比较运算符返回 1(或 True)表示真,返回 0(或 False)表示假。

OperatorsExplains
==相等
!=不等于
Python 3 已不支持 <>
>大于
<小于
>=大于等于 - 返回x是否大于等于y。
<=小于等于 - 返回x是否小于等于y。

赋值运算符
OperatorsExplains
`=赋值运算符
+=加法赋值运算符
-=减法赋值运算符
*=乘法赋值运算符
/=除法赋值运算符
%=取模赋值运算符
**=幂赋值运算符
//=取整除赋值运算符
:=海象运算符,可在表达式内部为变量赋值,然后直接进行判断。Python3.8 版本新增运算符。

位运算符
OperatorsExplain
&按位与运算符:
参与运算的两个值,如果两个相应位都为 1,则该位的结果为 1,否则为 0。
|按位或运算符:
只要对应的两个二进位有一个为 1 时,结果位就为 1。
^按位异或运算符:
当两对应的二进位相异时,结果为 1。
~按位取反运算符:
对数据的每个二进制位取反,即把 1 变为 0,把 0 变为 1。~x 类似于 x-1
<<左移动运算符:
运算数的各二进位全部左移若干位,由 << 右边的数指定移动的位数,高位丢弃,低位补 0。
>>右移动运算符:
把 >> 左边的运算数的各二进位全部右移若干位,>> 右边的数指定移动的位数。

逻辑运算符
OperatorsexpressionsExplains
andx and y布尔 “与”
如果 x 为 False,x and y 返回 x 的值,
否则返回 y 的计算值。
orx or y布尔 “或”
如果 x 是 True,它返回 x 的值,
否则它返回 y 的计算值。
notnot x布尔 “非”
如果 x 为 True,返回 False。
如果 x 为 False,它返回 True。

成员运算符
OperatorsExplains
in如果在指定的序列中找到值返回 True,否则返回 False。
not in如果在指定的序列中没有找到值返回 True,否则返回 False。

身份运算符
OperatorsExplains
is判断两个标识符是不是引用自一个对象。
x is y,类似 id(x) == id(y)。
如果引用的是同一个对象则返回 True,否则返回 False
is not判断两个标识符是不是引用自不同对象。
x is not y,类似 id(a) != id(b)。
如果引用的不是同一个对象则返回结果 True,否则返回 False。

is 和 == 的区别:

>>>a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True

运算符优先级

优先级按从高到底排列:

OperatorsExplains
**指数
~ + -按位翻转,一元加号和减号(最后两个的方法名为 +@ 和 -@)
* / % //乘,除,求余数和取整除
+ -加法减法
>> <<右移,左移运算符
&位 “AND”
^ |位运算符
<= < > >=比较运算符
== !=等于运算符
= %= /= //= -= += *= **=赋值运算符
is is not身份运算符
in not in成员运算符
not and or逻辑运算符

if 条件控制

if 语句的形式:

if condition_1:
    statement_block_1
elif condition_2:
    statement_block_2
else:
    statement_block_3

if 语句的条件通常由关系运算符或返回值为布尔值的语句组成,使用逻辑运算符在一条 if 语句中连接多个条件。


循环语句

Python 有 while 和 for 两种循环语句。


while 条件循环

while 循环的一般用法是,当指定条件成立时执行一次 while 后的代码块。

while condition:
    statements_block

while 语句后可接 else 语句。当指定条件不成立时,执行一次 while 后面的 else 语句。

while condition:
    statements_block_1
else:
    statements_block_2

for 循环遍历

for 循环的一般用法是,遍历任何可迭代对象。每次循环,都会从指定的可迭代对象中选取一个赋给指定的变量。如此循环下去,直到遍历完指定的可迭代对象中所有元素。

for variables in sequence:
    statements_block

for 语句后可接 else 语句。当指定的可迭代对象为空时,执行一次 for 后面的 else 语句。

for variable in sequence:
    statements_block_1
else:
    statements_block_2

for 循环经常与 range() 函数一起使用。当需要遍历数字序列时,可以使用 range() 函数生成数列。

# 输出数字 5~12
for i in range(5, 13):
    print(i, end=' ')

print('')    # 输出一个换行符

遍历技巧

在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:

>>> dict = {'one':1, 'two': 2, 'three': 3}
>>> for key, val in dict.items():
...     print(key, ' = ', val)
...
one  =  1
two  =  2
three  =  3

在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:

>>> for index, val in enumerate(['one', 'two', 'three']):
...     print(index, ': ', val)
...
0 :  one
1 :  two
2 :  three

同时遍历两个或更多的序列,可以使用 zip() 组合:

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

反向遍历序列,可以调用 reversed() 函数:

>>> for i in reversed(range(10)):
...     print(i, end = '')
...
9876543210

要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

break and continue
  • break 语句 —— 跳出(终止)循环。不执行当前循环块中 break 语句以下的语句,并且将控制转移到当前循环语句的下一条语句。
  • continue 语句 —— 进入下一轮循环。不执行当前循环块中 continue 语句以下的语句,并且将控制转义到循环语句的开头。

break 和 continue 在循环语句中使用。一般在循环中的 if 条件语句中使用。即,达到某个条件便结束或进入下一次循环。


pass 语句

pass 语句是空语句,即不执行任何操作。pass 是为了保持 Python 程序结构的完整性。

pass 一般作为占位语句,当操作都在条件语句或循环语句中完成时,在语句块中使用 pass 占位。如:

if condition_1:
    pass

while condition_2:
    pass

for variable in sequence:
    pass

迭代器与生成器 迭代器

迭代是一种访问集合元素的方式。迭代器是一个可以记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退

迭代器有两个基本的方法:iter() 和 next()。

字符串、列表或元组对象都可用于创建迭代器。

>>> list = [1, 2, 3, 4]
>>> it = iter(list)     # 创建迭代器对象
>>> print(next(it))		# 输出迭代器的下一个元素
1
>>> print(next(it))
2

迭代器对象可以使用常规 for 语句进行遍历:

list = [1, 2, 3, 4]
it = iter(list)		# 创建迭代器对象
for x in it:
    print(x, end = ' ')

使用 next() 迭代:

import sys         # 引入 sys 模块
 
list=[1, 2, 3, 4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()

创建迭代器

把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

  • __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__()方法并通过 StopIteration 异常标识迭代的完成。

  • __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)

i = 0
while i < 10:
    print(next(myiter), end = ' ')
    i += 1

# 输出:1 2 3 4 5 6 7 8 9 10

迭代结束标志

StopIteration 异常用于标识迭代的完成,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

# 迭代 10 次后停止
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x, end = ' ')

# 输出:1 2 3 4 5 6 7 8 9 10

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator),生成器是一个返回迭代器的函数,只能用于迭代操作。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 1, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1

f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

# 输出:1 1 2 3 5 8 13 21 34 55 89

函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。

函数的定义形式:

def function_name(arguments):
    """explain"""
    statements_block
    return [expression]
# end function_name
  • explain 是使用文档字符串存放的函数说明。
  • return 代表一个函数的结束,并且返回一个值给调用方,这个值放在 return 后面,可以是具体的值也可以是一条有确切值的表达式。不带值或表达式的 return 相当于返回 None。当函数不需要返回值时,可以省略 return。

调用一个函数时需要使用该函数名并根据其定义指定参数:

def function_name(arguments):
    """explain"""
    statements_block
    return [expression]
# end function_name

function_name(arguments)

参数
  • 不可变类型的参数传递:类似 C++ 的值传递。传递的只是参数的值,没有影响参数对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。即,修改参数之前函数内部参数的地址和函数外部参数的地址相同,一旦修改了变量,参数的地址将会发生变化。如 Number、String、Tuple。
  • 可变类型的参数传递:类似 C++ 的引用传递。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响。无论是否对参数进行修改,参数地址都不会发生改变。如 List、Dictionary、Set。

参数类型:

  • 必须参数:须以正确的顺序传入函数。调用时,必须参数的数量必须和声明时一样。

  • 关键字参数:函数调用时使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

    def func(a, b):
        print('a = ', a, 'b = ', b)
        return
    
    func(b = 2, a = 1)
    
  • 默认参数:调用函数时,如果没有传递参数,则会使用默认参数。默认参数在定义函数时定义。

    def func(a, b = 1)
    	print('a = ', a, 'b = ', b)
        return
    
    func(2)
    
  • 不定长参数:

    • 加了星号 * 的参数会以元组的形式导入,存放所有未命名的变量参数。

      def func(atg1, *vartuple):
          print(atg1, vartuple)
          return
      
      func(1, 2, 3)
      # 输出:1 (2, 3)
      
    • 加了两个星号 ** 的参数会以字典的形式导入。

      def func(atg1, **vartuple):
          print(atg1, vartuple)
          return
      
      func(1, a = 2, b = 3)
      # 输出:1 {'a': 2, 'b': 3}
      
    • 如果参数单独出现星号 * 后的参数必须用关键字传入。

      >>> def f(a,b,*,c):
      ...     return a+b+c
      ... 
      >>> f(1,2,3)   # 报错
      Traceback (most recent call last):
        File "", line 1, in 
      TypeError: f() takes 2 positional arguments but 3 were given
      >>> f(1,2,c=3) # 正常
      6
      
  • 强制位置参数:Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。

    def f(a, b, /, c):
        print(a, b, c)
        return
    
    # 形参 a 和 b 必须使用指定位置参数,c 可以是位置形参或关键字形参
    f(1, 2, c = 3)
    

匿名函数

Python 使用 lambda 来创建匿名函数。

  • lambda 的主体是一个表达式,而不是一个代码块(比 def 简单很多)。仅仅能在 lambda 表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然 lambda 函数看起来只能写一行,却不等同于 C 或 C++ 的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

lambda 函数的语法:

lambda [arg1 [,arg2,.....argn]]: expression

用法:

>>> sum = lambda arg1, arg2: arg1 + arg2
>>> sum(1, 2)
3

模块

模块是一个包含函数定义和变量的文件,其后缀名是 .py。

  • 模块可以被别的程序引入,以使用该模块中的函数等功能。
  • Python 标准库也是一个个内置的模块。
    这些模块会根据不同的操作系统进行不同的配置,不同的操作系统可能会有一些不同的模块。
  • 每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用,可以使用 dir() 查看。
    在导入模块后,可以通过 modname.itemname 这样的表示法来访问模块内的函数。
  • 模块可以被导入其他模块。被导入的模块的名称将被放入当前操作的模块的符号表中。
  • 模块除了方法定义,还可以包括可执行的代码。
    这些代码一般用来初始化这个模块,只有在第一次被导入时才会被执行。

包是一种管理 Python 模块命名空间的形式,采用 “点模块名称”。如一个模块的名称是 A.B, 那么他表示一个包 A 中的子模块 B。优点是不用担心不同模块之间的名称冲突。

包结构实例:

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

包还提供一个额外的属性 __path__。这是一个目录列表,里面每一个包含的目录都有为这个包服务的 __init__.py,得在其他 __init__.py 被执行前定义。可以修改这个变量,用来影响包含在包里面的模块和子包。这个功能并不常用,一般用来扩展包里面的模块。


import 语句
import module1[, module2[,... moduleN]

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。import 命令一般放在脚本顶端,如:

#!/usr/bin/python3
# Filename: support.py
 
def print_hello():
    print ('Hello World!')
    return
#!/usr/bin/python3
# Filename: test.py
 
# 导入模块
import hello
 
# 使用 . 运算符调用模块中的函数
hello.print_hello()

对于同一个模块,无论执行了多少次 import 语句,一个模块只会被导入一次。

搜索路径是一个解释器会先进行搜索的所有目录的列表,由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块(很像环境变量)。搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量。

以 Windows 系统为例(在 VS2017 中安装的 Python3):

>>> import sys
>>> print(sys.path)
['', 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python36.zip', 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\DLLs', 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib', 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64', 'C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\site-packages']

sys.path 输出是一个列表,其中第一项是空串,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),即我们执行 Python 解释器的目录(对于脚本的话就是运行的脚本所在的目录)。

如果要引入一些不在搜索路径中的模块,可以在脚本中修改 sys.path。

如果要经常使用一个模块中的函数,可以赋给它一个本地名称:

import module

func = module.func
func(arg)

from … import 语句

使用 from ... import 语句可以从模块中导入一个指定的部分到当前命名空间中。这种导入的方法不会把被导入的模块的名称放在当前的字符表中。

from modname import item1[, item2[, ... itemN]]

这样只会把 modname 中的指定的部分 item1[, item2[, ... itemN]] 导入到当前命名空间中,并且可以直接使用它们的名称来调用它们(无需使用 . 运算符)。item1[, item2[, ... itemN]] 可以是子模块、函数、类或变量等。

使用 from package import item 这种形式的时候,import 语法会首先把 item 当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,抛出一个 :exc:importError 异常。

把一个模块的所有内容全都导入到当前的命名空间(不要过多地使用该方法),但是那些由单一下划线 _ 开头的名字不在此例:

from modname import *

Python 会进入文件系统,找到这个包里面所有的子模块,然后一个一个的把它们都导入进来。但这个方法在 Windows 平台上工作的就不是非常好,因为 Windows 是一个不区分大小写的系统。

为了解决这个问题,需要提供一个精确包的索引。导入语句遵循如下规则:

如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。

以下实例在 file:sounds/effects/_init_.py 中包含如下代码:

__all__ = ["echo", "surround", "reverse"]

__name__ 属性

一个模块被另一个程序第一次引入时,其主程序将运行。可以用 __name__ 属性来使该程序块仅在该模块自身运行时执行(被其它程序或模块引入时不执行)。

每个模块都有一个 __name__ 属性,当其值是 '__main__' 时,表明该模块自身在运行,否则是被引入。

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
$ python using_name.py
程序自身在运行
$ python
>>> import using_name
我来自另一模块

dir() 函数

内置的函数 dir() 可以找到指定模块内定义的所有名称,以一个字符串列表的形式返回。

>>> import math
>>> dir(math)
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

如果没有给定参数,dir() 函数会罗列出当前定义的所有名称。

>>> a = [1, 2, 3]
>>> b = 4
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b']

输入输出 标准输出

在 Python 中使用 print() 来将其参数输出到标准输出上。默认的标准输出是屏幕。

可以使用 str.format() 函数等方式⤴️ 来格式化输出值。

可以使用 repr() 或 str() 函数来将输出的值转成字符串。

  • str():函数返回一个用户易读的表达形式。
  • repr():产生一个解释器易读的表达形式。

标准输入

Python 提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。

Python3.x 中 input() 函数接受一个标准输入数据,返回为 string 类型。Python3.x 没有 raw_input()。

input() 函数的语法:

input([prompt])
# prompt —— 输出到标准输出的提示信息

用法示例:

>>> a = input('输入一个整数:')
输入一个整数:123
>>> type(a)
			# input() 返回的是 string
>>> a = int(a)			# 使用 int() 类型转换
>>> print(type(a), a)
 123		# 此时 a 才是 int

input() 接收多个值:

#输入三角形的三边长
a, b, c = (input("请输入三角形三边的长:").split())
a = int(a)
b = int(b)
c = int(c)

#计算三角形的半周长p
p = (a + b + c) / 2

#计算三角形的面积s
s = (p * (p - a) * (p - b) * (p - c))**0.5

#输出三角形的面积
print("三角形面积为:", format(s, '.2f'))

读写文件

open() 将会返回一个 file 对象,基本语法格式如下:

open(filename[, mode='r'])
# filename —— 包含了要访问的文件名称的字符串值
# mode —— 打开文件的模式的字符串值,默认文件访问模式为只读(r)

打开文件的模式:

模式描述
t文本模式 (默认)。
x写模式,新建一个文件,如果该文件已存在则会报错。
b二进制模式。
+打开一个文件进行更新(可读可写)。
U通用换行模式(不推荐)。
r以只读方式打开文件(默认模式)。文件的指针将会放在文件的开头。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w打开一个文件只用于写入。
如果该文件已存在,则清空原文件内容,并从开头开始编辑。
如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。
打开方式与 w 相同(会覆盖原有的文件)。
w+打开一个文件用于读写。
打开方式与 w 相同。
wb+以二进制格式打开一个文件用于读写。
打开方式与 w 相同。
a打开一个文件用于追加。
如果该文件已存在,文件指针将会放在文件的结尾。
即,新的内容将会被写入到已有内容之后。
如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。
打开方式与 a 相同。
a+打开一个文件用于读写。
打开方式与 a 相同。
ab+以二进制格式打开一个文件用于追加。
打开方式与 a 相同。

下图总结了这几种模式:

模式rr+ww+aa+
++++
+++++
创建++++
覆盖++
指针在开始++++
指针在结尾++

open() 函数的完整语法格式:

open(file[, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None])
# file —— 必需,文件路径(相对或者绝对路径)。
# mode —— 可选,文件打开模式
# buffering —— 设置缓冲
# encoding —— 一般使用 utf8
# errors —— 报错级别
# newline —— 区分换行符
# closefd —— 传入的 file 参数类型
# opener —— 自定义打开文件方式

打开文件后,要进行的就是写入和读取操作,这些操作都是对 file 对象进行操作。

file 对象方法:

方法说明
file.close()关闭文件。关闭后文件不能再进行读写操作。
在执行完文件的读写操作后,有必要执行该方法。
file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
file.fileno()返回一个整型的文件描述符(file descriptor FD 整型),可以用在如 os 模块的 read 方法等一些底层操作上。
file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。
file.next()返回文件下一行。
file.read([size=-1])从文件读取指定的字节数,默认为 -1,为负数时表示读取所有。
file.readline([size=-1])读取整行(size 默认为 -1,为负数表示读取整行),包括 'n' 字符。
如果指定了 size 则读取该行的前 size 字符。
第一次调用时读取第一行,第二次调用时读取第二行,以此类推。
file.readlines([sizeint])读取所有行并返回列表,若给定 sizeint > 0,则是设置一次读多少字节,这是为了减轻读取压力。
file.seek(offset[, whence=0])设置文件当前位置。
offset —— 开始的偏移量。
whence —— 给 offset 参数一个定义,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。默认为 0。
file.tell()返回文件当前位置。
file.truncate([size=file.tell()])截取文件,截取的字节通过 size 指定,默认为当前文件位置。
file.write(str)将字符串写入文件,返回的是写入的字符长度。
如果文件打开模式带 b,那写入文件内容时,str 要用 encode() 方法转为 bytes 形式,否则报错:TypeError: a bytes-like object is required, not ‘str’。
file.writelines(sequence)向文件写入一个序列字符串列表(这一序列字符串可以是由迭代对象产生的,如一个字符串列表),如果需要换行则要自己加入每行的换行符。

file.write() 用法:

f = open('test.txt', 'w+')
f.write('test1')
f.seek(0)
print('从文件中读取到的字符串:', f.read())
f.close()
# 输出:
# 从文件中读取到的字符串: test1

f = open('test.txt', 'wb+')
f.write('test1'.encode())
f.seek(0)
print('从二进制文件中读取到的内容:', f.read())
f.seek(0)
print('将其转化为字符串输出:', f.read().decode())
f.close()
# 输出:
# 从二进制文件中读取到的内容: b''
# 将其转化为字符串输出: test1

方法说明
file.close()关闭文件。关闭后文件不能再进行读写操作。
在执行完文件的读写操作后,有必要执行该方法。
file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
file.fileno()返回一个整型的文件描述符(file descriptor FD 整型),可以用在如 os 模块的 read 方法等一些底层操作上。
file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。
file.next()返回文件下一行。
file.read([size=-1])从文件读取指定的字节数,默认为 -1,为负数时表示读取所有。
file.readline([size=-1])读取整行(size 默认为 -1,为负数表示读取整行),包括 'n' 字符。
如果指定了 size 则读取该行的前 size 字符。
第一次调用时读取第一行,第二次调用时读取第二行,以此类推。
file.readlines([sizeint])读取所有行并返回列表,若给定 sizeint > 0,则是设置一次读多少字节,这是为了减轻读取压力。
file.seek(offset[, whence=0])设置文件当前位置。
offset —— 开始的偏移量。
whence —— 给 offset 参数一个定义,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。默认为 0。
file.tell()返回文件当前位置。
file.truncate([size=file.tell()])截取文件,截取的字节通过 size 指定,默认为当前文件位置。
file.write(str)将字符串写入文件,返回的是写入的字符长度。
如果文件打开模式带 b,那写入文件内容时,str 要用 encode() 方法转为 bytes 形式,否则报错:TypeError: a bytes-like object is required, not ‘str’。
file.writelines(sequence)向文件写入一个序列字符串列表(这一序列字符串可以是由迭代对象产生的,如一个字符串列表),如果需要换行则要自己加入每行的换行符。

file.write() 用法:

f = open('test.txt', 'w+')
f.write('test1')
f.seek(0)
print('从文件中读取到的字符串:', f.read())
f.close()
# 输出:
# 从文件中读取到的字符串: test1

f = open('test.txt', 'wb+')
f.write('test1'.encode())
f.seek(0)
print('从二进制文件中读取到的内容:', f.read())
f.seek(0)
print('将其转化为字符串输出:', f.read().decode())
f.close()
# 输出:
# 从二进制文件中读取到的内容: b''
# 将其转化为字符串输出: test1

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/272899.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号