Python基本语法
关键子和保留字
import keyword
print(len(keyword.kwlist)) #33
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']
函数
pow(2,3) => 2*2*2
- abs计算绝对值,round将浮点数圆整为与之最接近的整数
模块
用命令import的变种from module import function
,可在调 用函数时不指定模块前缀 可使用变量来引用函数(以及其他大部分Python元素)。
- 执行赋值语句
foo = math.sqrt
后,就可使用foo来计算平 方根。例如,foo(4)的结果为2.
字符串
- 原始字符串可派上用场,因为它们根本不会对反斜杠做特殊处理,而是让字符串包含的每个字符都保持原样。
>>> print(r'C:\nowhere')
C:\nowhere
>>> print(r'C:\Program Files\fnord\foo\bar\baz\frozz\bozz')
C:\Program Files\fnord\foo\bar\baz\frozz\bozz
# string
a='hello,{}'
print(a.find('o'))
print(a.format(" world !"))
print(a)
成员关系运算符 in not in
比较运算符 > < >= < = == != <>
函数 | 描述 |
---|---|
abs(number) | 返回指定数的绝对值 |
bytes(string, encoding[,errors]) | 对指定的字符串进行编码,并以指定的方式处理错误 |
cmath.sqrt(number) | 返回平方根;可用于负数 |
float(object) | 将字符串或数字转换为浮点数 |
help([object]) | 提供交互式帮助 |
input(prompt) | 以字符串的方式获取用户输入 |
int(object) | 将字符串或数转换为整数 |
math.ceil(number) | 以浮点数的方式返回向上圆整的结果 |
math.floor(number) | 以浮点数的方式返回向下圆整的结果 |
math.sqrt(number) | 返回平方根;不能用于负数 |
pow(x, y[, z]) | 返回x的y次方对z求模的结果 |
print(object, ...) | 将提供的实参打印出来,并用空格分隔 |
repr(object) | 返回指定值的字符串表示 |
round(number[, ndigits]) | 四舍五入为指定的精度,正好为5时舍入到偶 数 |
str(object) | 将指定的值转换为字符串。用于转换bytes时,可指定编码和错误处理方式 |
数据结构 列表和元组
列表
>>> edward = ['Edward Gumby', 42]
>>> john = ['John Smith', 50]
>>> database = [edward, john]
>>> database
[['Edward Gumby', 42], ['John Smith', 50]]
- 括索引、切片、相加、相乘和成员资格检查
- 所有元素都有编号——从0开始递增 因此-1是最后一个元素的位置
切片
- 使用切片(slicing)来访问特定范围内的元素。为此,可使用两个索引,并用冒号分隔
:
- 第一个索引是包含的第一个元素的编号
- 但第二个索引是切片后余下的第一个元素的编号。
- 如果切片结束于序列末尾,可省略第二个索引。
- 如果切片始于序列开头,可省略第一个索引。
>>> tag = '<a href="http://www.python.org">Python web site</a>'
>>> tag[9:30]
'http://www.python.org'
>>> tag[32:-4]
'Python web site'
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> numbers[3:6] [4, 5, 6]
>>> numbers[0:1] [1]
>>> numbers[-3:]
[8, 9, 10]
numbers[:3]
序列相加
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> 'python' * 5
'pythonpythonpythonpythonpython'
>>> [42] * 10
[42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
长度、最小值和最大值
内置函数len、min和max很有用,其中函数len返回序列包含的元素个 数,而min和max分别返回序列中最小和最大的元素
insert方法insert用于将一个对象插入列表。 pop从列表中删除一个元素(末尾为最后一个元素),并返回 列表中删除元素也很容易,只需使用del语句
修改列表如x[1] = 2
这一元素。
>>> numbers.insert(3, 'four')
>>> names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
>>> del names[2]
>>> x = [1, 2, 3]
>>> x.pop()
3
>>> x
[1, 2]
>>> x.pop(0)
1
>>> x
[2]
# 方法remove用于删除第一个为指定值的元素。
>>> x = ['to', 'be', 'or', 'not', 'to', 'be']
>>> x.remove('be')
切片赋值
>>> name = list('Perl')
>>> name
['P', 'e', 'r', 'l']
# 切片 2 截取 复制
>>> name[2:] = list('ar')
>>> name
['P', 'e', 'a', 'r']
a = list('Python Hello')
print(a)
a[2:] = list('中华')
print(a)
方法reverse按相反的顺序排列列表中的元素
- append 方法append用于将一个对象附加到列表末尾
- clear 方法clear就地清空列表的内容
- copy 方法copy复制列表。前面说过,常规复制只是将另一个名称关联到 列表
- count 方法count计算指定的元素在列表中出现了多少次
- index 方法index在列表中查找指定值第一次出现的索引
- extend 方法extend让你能够同时将多个值附加到列表末尾
- remove 方法remove用于删除第一个为指定值的元素
- insert 方法insert用于将一个对象插入列表。 注意 pop是唯一既修改列表又返回一个非None值的列表方 法。
sort 高级排序 方法sort接受两个可选参数:key和reverse。这两个参数通常是 按名称指定的,称为关键字参数
参数key类 似于参数cmp:你将其设置为一个用于排序的函数。然而,不会直 接使用这个函数来判断一个元素是否比另一个元素小,而是使用它 来为每个元素创建一个键,再根据这些键对元素进行排序。因此, 要根据长度对元素进行排序,可将参数key设置为函数len。
>>> x = ['aardvark', 'abalone', 'acme', 'add', 'aerate']
>>> x.sort(key=len)
>>> x
['add', 'acme', 'aerate', 'abalone', 'aardvark']
- 另一个关键字参数reverse,只需将其指定为一个真值(True或False ),以指出是否要按相反的顺序对 列表进行排序
>>> x = [4, 6, 2, 1, 7, 9]
>>> x.sort(reverse=True)
>>> x
[9, 7, 6, 4, 2, 1]
函数sorted也接受参数key和reverse。在很多情况下,将参 数key设置为一个自定义函数很有用
元组:不可修改的序列
- tuple 函数tuple的工作原理与list很像:它将一个序列作为参数,并将其转换为元组
如何表示只包含一个值的元组呢?这有点特殊:虽然只有 一个值,也必须在它后面加上逗号。
(10,)
函数 | 描述 |
---|---|
len(seq) | 返回序列的长度 |
list(seq) | 将序列转换为列表 |
max(args) | 返回序列或一组参数中的最大值 |
min(args) | 返回序列和一组参数中的最小值 |
reversed(seq) | 让你能够反向迭代序列 |
sorted(seq) | 返回一个有序列表,其中包含指定序列中的所有元素 |
tuple(seq) | 将序列转换为元组 |
字符串
"{}, {} and {}".format("first", "second", "third")
'first, second and third'
>>> "{0}, {1} and {2}".format("first", "second", "third")
'first, second and third'
类型 | 含义 |
---|---|
b | 将整数表示为二进制数 |
c | 将整数解读为Unicode码点 |
d | 将整数视为十进制数进行处理,这是整数默认使用的说明符 |
e | 使用科学表示法来表示小数(用e来表示指数) |
E | 与e相同,但使用E来表示指数 |
f | 将小数表示为定点数 |
F | 与f相同,但对于特殊值(nan和inf),使用大写表示 |
g | 自动在定点表示法和科学表示法之间做出选择。这是默认用于小数的说明符,但在默认情况下至少有1位小数 |
G | 与g相同,但使用大写来表示指数和特殊值 |
n | 与g相同,但插入随区域而异的数字分隔符 |
o | 将整数表示为八进制数 |
s | 保持字符串的格式不变,这是默认用于字符串的说明符 |
x | 将整数表示为十六进制数并使用小写字母 |
X | 与x相同,但使用大写字母 |
% | 将数表示为百分比值(乘以100,按说明符f设置格式,再在后面加上%) |
精度也是使用整数指定的,但需要在它前面加上一个表示小数点的句 点。
>>> "Pi day is {pi:.2f}".format(pi=pi)
'Pi day is 3.14'
fun str
center 方法center通过在两边添加填充字符(默认为空格)让字符串居中。
find 方法find在字符串中查找子串。如果找到,就返回子串的第一个字符的 索引,否则返回-1。
join join是一个非常重要的字符串方法,其作用与split相反,用于合并序 列的元素。 split split是一个非常重要的字符串方法,其作用与join相反,用于将字符 串拆分为序列。 lower 方法lower返回字符串的小写版本
replace 方法replace将指定子串都替换为另一个字符串,并返回替换后的结 果。
strip 方法strip将字符串开头和末尾的空白(但不包括中间的空白)删除, 并返回删除后的结果
>>> "The Middle by Jimmy Eat World".center(39)
' The Middle by Jimmy Eat World '
>>> "The Middle by Jimmy Eat World".center(39, "*")
'*****The Middle by Jimmy Eat World*****'
'With a moo-moo here, and a moo-moo there'.find('moo')
>>> subject.find('$$$', 1) # 只指定了起点
20
>>> subject.find('!!!')
16
>>> subject.find('!!!', 0, 16) # 同时指定了起点和终点
-1
seq = ['1', '2', '3', '4', '5']
>>> sep.join(seq) # 合并一个字符串列表
'1+2+3+4+5'
>>> dirs = '', 'usr', 'bin', 'env'
>>> ''.join(dirs)
'This is a test'.replace('is', 'eez')
'Theez eez a test'
'1+2+3+4+5'.split('+')
['1', '2', '3', '4', '5']
字典 dict
len(d)
返回字典d包含的项(键-值对)数。 d[k]
返回与键k相关联的值。 d[k] = v
将值v关联到键k。 del d[k]
删除键为k的项。 k in d
检查字典d是否包含键为k的项。
- 使用format_map来指出你将通过一个映射来提供所需的信
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
>>> items = [('name', 'Gumby'), ('age', 42)]
>>> d = dict(items)
>>> d = dict(name='Gumby', age=42)
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
>>> phonebook
{'Beth': '9102', 'Alice': '2341', 'Cecil': '3258'}
>>> "Cecil's phone number is {Cecil}.".format_map(phonebook)
"Cecil's phone number is 3258."
>>> from copy import deepcopy
>>> d = {}
>>> d['names'] = ['Alfred', 'Bertrand']
>>> c = d.copy()
>>> dc = deepcopy(d)
deepcopy(d)
字典方法
clear 方法clear删除所有的字典项,这种操作是就地执行的(就像 list.sort一样),因此什么都不返回(或者说返回None)。
深拷贝
copy 方法copy返回一个新字典,其包含的键-值对与原来的字典相同 (这个方法执行的是浅复制,因为值本身是原件,而非副本)。 from copy import deepcopy
深复制,即同时复制值及其包含 的所有值,等等。为此,可使用模块copy中的函数deepcopy
get 方法get为访问字典项提供了宽松的环境。通常,如果你试图访问 字典中没有的项 用get来访问不存在的键时,没有引发异常,而是返 回None。你可指定“默认”值,这样将返回你指定的值而不 是None。
items 方法items返回一个包含所有字典项的列表,其中每个元素都为 (key, value)的形式
keys 方法keys返回一个字典视图,其中包含指定字典中的键
pop 方法pop可用于获取与指定键相关联的值,并将该键-值对从字典中 删除。
>>> d = {'x': 1, 'y': 2}
>>> d.pop('x')
1
>>> d
{'y': 2}
update 方法update使用一个字典中的项来更新另一个字典
values 方法values返回一个由字典中的值组成的字典视图。不同于方法 keys,方法values返回的视图可能包含重复的值
fromkeys 方法fromkeys创建一个新字典,其中包含指定的键,且每个键对 应的值都是None。 items 方法items返回一个包含所有字典项的列表,其中每个元素都为 (key, value)的形式。字典项在列表中的排列顺序不确定。
popitem 方法popitem类似于list.pop,但list.pop弹出列表中的最后一 个元素,而popitem随机地弹出一个字典项,因为字典项的顺序是 不确定的,没有“最后一个元素”的概念。如果你要以高效地方式逐 个删除并处理所有字典项,这可能很有用,因为这样无需先获取键 列表。
>>> d = {
... 'title': 'Python Web Site',
... 'url': 'http://www.python.org',
... 'changed': 'Mar 14 22:09:15 MET 2016'
... }
>>> x = {'title': 'Python Language Website'}
>>> d.update(x)
>>> d
{'url': 'http://www.python.org', 'changed':
'Mar 14 22:09:15 MET 2016', 'title': 'Python Language Website'}
>>> {}.fromkeys(['name', 'age'])
{'age': None, 'name': None}
再谈print和import
在语句末尾添加as子句并指定别名。下面是一个导入 整个模块并给它指定别名的例子
>>> import math as foobar
>>> foobar.sqrt(4)
2.0
>>> from math import sqrt as foobar
>>> foobar(4)
2.0
赋值魔法
序列解包
赋值语句你见过很多,有的给变量赋值,还有的给数据结构的一部分 (如列表中的元素和切片,或者字典项)赋值,但还有其他类型的赋值 语句。例如,可同时(并行)给多个变量赋值
>>> x, y, z = 1, 2, 3
>>> print(x, y, z)
1 2 3
# 交换
>>>> x, y = y, x
>>>> print(x, y, z)
>2 1 3
- 这里执行的操作称为序列解包(或可迭代对象解包):将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中
要解包的序列包含的元素个数必须与你在等号左边列出 的目标个数相同,否则Python将引发异常
可使用星号运算符(*)来收集多余的值,这样无需确保值和变量的个 数相同,如下例所示 赋值语句的右边可以是任何类型的序列,但带星号的变量最终包含的总 是一个列表。在变量和值的个数相同时亦如此。
>>> a, b, *rest = [1, 2, 3, 4]
>>> rest
[3, 4]
>>> a, *b, c = "abc"
>>> a, b, c
('a', ['b'], 'c')
x,y,*z = range(1,8,2)
print(x,y,z)
代码块:缩进的乐趣
可在满足条件时执行(if语句),可执行多次(循环),等等。代码块是通过缩进代码(即在前面加空格)来创建的。注意 也可使用制表符来缩进代码块。Python将制表符解释为移到下一个制表位(相邻制表位相距8个空格),但标准(也是更佳的)做法是只使用空格(而不使用制表符)来缩进,且每级缩进4个空格。
在Python中,使用冒号(:)指出接下来是一个代码块
条件表达式
# 用作布尔表达式(如用作if语句中的条件)时,下面的值都将被解释器视为假:
False None 0 "" () [] {}
Python比较运算符
表达式 | 描述 |
---|---|
x == y | x等于y |
x < y | x小于y |
x > y | x大于y |
x >= y | x大于或等于y |
x <= y | x小于或等于y |
x != y | x不等于y |
x is y | x和y是同一个对象 |
x is not y | x和y是不同的对象 |
x in y | x是容器(如序列)y的成员 |
x not in y | x不是容器(如序列)y的成员 |
断言 使用关键字assert。
- 在条件后面添加一个字符串,对断言做出说明。
>>> age = -1
>>> assert 0 < age < 100, 'The age must be realistic'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AssertionError: The age must be realistic
循环
并行迭代
有时候,你可能想同时迭代两个序列。假设有下面两个列表:
names = ['anne', 'beth', 'george', 'damon']
ages = [12, 45, 32, 102]
如果要打印名字和对应的年龄,可以像下面这样做:
for i in range(len(names)):
print(names[i], 'is', ages[i], 'years old')
简单推导
列表推导是一种从其他列表创建列表的方式,类似于数学中的集合推 导。列表推导的工作原理非常简单,有点类似于for循环。
y =[x +x -1 for x in range(10) ]
print(y)
作用域
变量到底是什么呢?可将其视为指向值的名称。因此,执行赋值语句x = 1后,名称x指向值1。这几乎与使用字典时一样(字典中的键指向 值),只是你使用的是“看不见”的字典。实际上,这种解释已经离真相 不远。有一个名为vars的内置函数,
vars()
递归示例——二分查找算法。
- 你可能熟悉猜心游戏。这个游戏要求猜对对方心里想的是什么,且整个猜测过程提出的“是否”问题不能超过20个。为充分利用每个问题,你力图让每个问题的答案将可能的范围减半。
- 例如,如果你知道对方心里想的是一个人,可能问:“你心里想的是个女人吗?”除非你有很强的第六感,不然不会一开始就问:“你心里想的是John Cleese吗?”
- 对喜欢数字的人来说,这个游戏的另一个版本是猜数。例如,对方心里想着一个1~100的数字,你必须猜出是哪个。 当然,猜100次肯定猜对,但最少需要猜多少次呢? 实际上只需猜7次。 首先问:“这个数字大于50吗?” 如果答案是肯定的,再问:“这个数字大于75吗?” 不断将可能的区间减半,直到猜对为止。你无需过多地思考就能成功。
def search(sequence, number, lower, upper):
if lower == upper:
assert number == sequence[upper]
return upper
else:
middle = (lower + upper) // 2
if number > sequence[middle]:
return search(sequence, number, middle + 1, upper)
else:
return search(sequence, number, lower, middle)
函数 | 描述 |
---|---|
map(func, seq[, seq, ...]) | 对序列中的所有元素执行函数 |
filter(func, seq) | 返回一个列表,其中包含对其执行函数时结果为真的所 有元素 |
reduce(func, seq[, initial]) | 等价于func(func(func(seq[0], seq[1]), seq[2]), ...) |
sum(seq) | 返回seq中所有元素的和 |
apply(func[, args[, kwargs]]) | 调用函数(还提供要传递给函数的参数) |