Python知识点(一) 运算符和表达式

“+”运算符不支持不同内置类型的对象之间相加或连接。

1
2
 'A' + 1                            #不支持字符与数字相加,抛出异常
TypeError: can only concatenate str (not "int") to str

”运算符 §列表、字符串或元组等类型变量与整数进行“”运算时,表示对内容进行重复并返回重复后的新对象。

1
2
3
4
5
6
 'a' * 10                    #字符串重复
'aaaaaaaaaa'
[1,2,3] * 3 #列表重复
[1, 2, 3, 1, 2, 3, 1, 2, 3]
(1,2,3) * 3 #元组重复
(1, 2, 3, 1, 2, 3, 1, 2, 3)

“/”和“//”分别表示除法和整除运算。

同一性测试运算符(identity comparison)is用来测试两个对象是否引用同一个地址,如果是则返回True,否则返回False。如果两个对象引用了同一个对象,二者具有相同的内存地址。

1
2
3
4
5
6
7
8
9
10
11
 3 is 3
True

x = [300, 300, 300]
x[0] is x[1] #基于值的内存管理,同一个值在内存中只有一份
True

x = [1, 2, 3]
y = [1, 2, 3]
x is y #上面形式创建的x和y不是同一个列表对象
False

Python不支持++和–运算符,只是两个连续的加号和减号。

and和or具有惰性求值特点,只计算必须计算的表达式。

1
2
3
4
5
3>5 or a>3           # 3>5的值为False,所以需要计算后面表达式
NameError: name 'a' is not defined

3<5 or a>3 #3<5的值为True,不需要计算后面表达式
True

Python知识点(二) 常用内置函数

eval()

去掉参数最外侧引号并执行余下语句的函数

1
2
3
4
5
6
7
8
eval("1")
1

eval("1+2")
3

eval('print("Hello")')
Hello

divmod(x, y)

计算整商和余数,返回元组(x//y, x%y)

range()

语法格式为range([start,] end [, step] ),返回具有惰性求值特点的range对象,其中包含左闭右开区间[start,end)内以step为步长的整数。

map(func, *iterables)

把一个可调用对象func依次映射到一个或多个可迭代对象的每个元素上,并返回一个可迭代的map对象作为结果,map对象中每个元素是原可迭代对象中元素经过可调用对象func处理后的结果。

1
2
3
4
5
6
7
 def add(x, y):            #可以接收2个参数的函数
return x+y

list(map(add, range(5), range(5,10))) #把双参数函数映射到两个序列上

[5, 7, 9, 11, 13] # 输出结果

sorted(key=None,reverse=False)

返回排序后的列表,参数key用来指定排序规则或依据,参数reverse用来指定升序或降序,默认为升序。

filter(function or None, iterable)

将一个单参数可调用对象作用到一个可迭代对象上,返回其中使得可调用对象返回值等价于True的那些元素组成的filter对象,如果指定filter()函数第一个参数为None,则返回可迭代对象中等价于True的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
seq = ['foo', 'x41', '?!', '***']
def func(x):
return x.isalnum() #测试是否为字母或数字

filter(func, seq) #返回filter对象
<filter object at 0x000000000305D898>

list(filter(func, seq)) #把filter对象转换为列表
['foo', 'x41']

list(filter(str.isalnum, seq)) #等价的用法
['foo', 'x41']

data = list(range(20))
filterObject = filter(lambda x:x%2==1, data) #过滤,只留下所有奇数

filterObject
<filter object at 0x000001D602B85828>

3 in filterObject #3以及3之前的元素都访问过了
True

list(filterObject) #现在所有元素都访问过了
[5, 7, 9, 11, 13, 15, 17, 19]

list(filterObject) #filterObject中不再包含任何元素,因为filter对象具有惰性求值的特点
[]

reduce(function, sequence[, initial])

可以将一个接收2个参数的可调用对象以迭代累积的方式从左到右依次作用到一个可迭代对象的所有元素上,并且允许指定一个初始值。在Python 3.x中reduce()不是内置函数,需要从标准库functools中导入再使用。

1
2
3
4
from functools import reduce
seq = list(range(1, 10)) # 数据
reduce(lambda x, y: x+y, seq) # 累加并返回结果 输出结果 45

迭代累加

round(number, ndigits=None)

对number进行四舍五入,最终结果保留ndigits位小数。

enumerate()

函数用来枚举可迭代对象中的元素,返回可迭代的enumerate对象,其中每个元素都是包含索引和值的元组。

1
2
list(enumerate('abcd'))            #枚举字符串中的元素
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

bin()、oct()、hex()

将**整数**转换为二进制、八进制和十六进制形式。

zip()

函数用来把多个可迭代对象中对应位置上的元素组合到一起,返回一个可迭代的zip对象,其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组,如同拉拉链一样。

1
2
3
4
5
6
list(zip('abcd', [1, 2, 3]))  # 输出结果  [('a', 1), ('b', 2), ('c', 3)]

list(zip('123', 'abc', ',.!')) # 输出结果 [('1', 'a', ','), ('2', 'b', '.'), ('3', 'c', '!')]

# 可以看到结果列表中的每个成员都是元组类型

最后注意:

map、filter、enumerate、zip等对象不仅具有惰性求值的特点,还有另外一个特点:访问过的元素不可再次访问。

1
2
3
4
5
6
7
x = map(str, range(10))   
list(x)
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

list(x)
[] # 失效了

阶段练习

用户输入一个三位自然数,计算并输出其佰位、十位和个位上的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 第一种
x = int(input('请输入一个三位数:'))
a, b = divmod(x, 100)
b, c = divmod(b, 10)
print(a, b, c)

# 第二种
x = input('请输入一个三位数:')
a, b, c = map(int, x)
print(a, b, c)

# 第三种 不限位数
x = input('请输入一个n位自然数:')
print(*map(int, x))

任意输入三个英文单词,按字典顺序输出。

1
2
3
4
s = input('x,y,z=')
x, y, z = sorted(s.split(',')) # 逗号分隔
print(x, y, z)


Python知识点(三) Python序列

概述

列表

列表增加

使用列表对象的extend()方法可以将另一个可迭代对象的所有元素添加至该列表对象尾部。通过extend()方法来增加列表元素也不改变其内存首地址,属于原地操作

1
2
3
4
5
6
7
8
9
aList = [3, 4, 5, 7, 9]
aList.extend([11,13])
aList
[3, 4, 5, 7, 9, 11, 13]

aList.extend((15,17))
aList
[3, 4, 5, 7, 9, 11, 13, 15, 17]

使用列表对象的insert()方法将元素添加至列表的指定位置。

1
2
3
4
aList.insert(3, 6)                #在下标为3的位置插入元素6
aList
[3, 4, 5, 6, 7, 9, 11, 13, 15, 17]

当使用*运算符将包含列表的列表重复并创建新列表时,并不是复制子列表值,而是复制已有元素的引用。因此,当修改其中一个值时,相应的引用也会被修改。

1
2
3
4
5
6
7
8
x = [[None] * 2] * 3
x
[[None, None], [None, None], [None, None]]

x[0][0] = 5
x
[[5, None], [5, None], [5, None]]

列表删除

del命令

pop()方法删除并返回指定位置(默认为最后一个)

remove()方法删除首次出现的指定元素,如果列表中不存在要删除的元素,则抛出异常。

注:列表有自动内存管理功能。在删除列表元素时,Python会自动对列表内存进行收缩并移动列表元素以保证所有元素之间没有空隙,增加列表元素时也会自动扩展内存并对元素进行移动以保证元素之间没有空隙。每当插入或删除一个元素之后,该元素位置后面所有元素的索引就都改变了。

1
2
3
4
5
6
正确的删除代码:
x = [1,2,1,2,1,1,1]
for i in range(len(x)-1,-1,-1): #从后往前删
if x[i]==1:
del x[i]

列表切片

切片返回的是浅复制。所谓浅复制,是指生成一个新的列表,并且把原列表中所选元素的引用都复制到新列表中。如果原列表中只包含整数、实数、复数等基本类型或元组、字符串这样的不可变类型的数据,一般是没有问题的。

1
2
3
4
5
6
7
8
9
10
11
12
13
aList = [3, 5, 7]
bList = aList[::] #切片,浅复制
aList == bList #两个列表的元素完全一样
True
aList is bList #但不是同一个对象
False
id(aList) == id(bList) #内存地址不一样
False
bList[1] = 8 #修改其中一个不会影响另一个
bList
[3, 8, 7]
aList
[3, 5, 7]

如果原列表中包含列表之类的可变数据类型,由于浅复制时只是把子列表的引用复制到新列表中,这样的话修改任何一个都会影响另外一个。

1
2
3
4
5
6
7
8
9
10
aList = [3, [5], 7]        #列表aList中包含可变的列表对象
bList = aList[:] #切片
bList[1].append(6) #调用子列表的append()方法,这个方法是原地操作的

bList
[3, [5, 6], 7]

aList #aList受到影响
[3, [5, 6], 7]

标准库copy中的deepcopy()函数实现深复制。所谓深复制,是指对原列表中的元素进行递归,把所有的值都复制到新列表中,对嵌套的子列表不再是复制引用。新列表和原列表是互相独立,修改任何一个都不会影响另外一个

1
2
3
4
5
6
7
8
9
10
11
12
13
aList = [3, [5], 7]
import copy
bList = copy.deepcopy(aList) #深赋值,递归复制,直到遇到可哈希对象
#aList和bList完全独立,互相不影响
aList == bList
True
aList is bList
False
bList[1].append(6) #修改bList不会影响aList
bList
[3, [5, 6], 7]
aList
[3, [5], 7]

以下这张图深刻地解释了切片复制的原理:不可变类型数据不影响(指向不同的内存地址),可变类型数据影响(指向相同的内存地址)

列表排序

sort()方法进行原地排序

sorted()对列表进行排序并返回新列表

reverse()方法将元素原地逆序。

reversed()对列表元素进行逆序排列并返回迭代器对象。

注:sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
aList.sort() #默认是升序排序
aList.sort(reverse=True) #降序排序
aList.sort(key=lambda x:len(str(x))) #按转换成字符串的长度排序

sorted(aList) #升序排序,默认是按字母的ascii编码顺序
sorted(aList,reverse=True) #降序排序

aList.reverse() # 原地逆序

newList = reversed(aList) #返回reversed对象
for i in newList:
print(i, end=' ') #输出结果 17 15 13 11 9 7 6 5 4 3


t1 = 'gadfsf'
t2 = (3,1,2)
s1 = sorted(t1) # 对不可变序列的元组和字符串进行排序
s2 = sorted(t2)
s1 # 输出结果 ['a', 'd', 'f', 'f', 'g', 's']
s2 # 输出结果 [1, 2, 3]
# 可以看出排序后返回的是一个新列表

用于序列操作的常用内置函数

any(iterable)

参数
iterable – 元组或列表
返回值
如果都为空、0、false,则返回false,如果不都为空、0、false,则返回true。有点类似于或运算(or)

all(iterable)

参数
iterable – 元组或列表。
返回值
如果iterable的所有元素不为0、’’、False或者iterable为空,all(iterable)返回True,否则返回False;

注意:空元组、空列表返回值为True,这里要特别注意。

其他

len(列表):返回列表中的元素个数

max(列表)、 min(列表):返回列表中的最大或最小元素

sum(列表):对列表的元素进行求和运算

zip()函数返回可迭代的zip对象

enumerate(列表):枚举列表元素,返回枚举对象,其中每个元素为包含下标和值的元组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
aList = [1, 2, 3]
bList = [4, 5, 6]
cList = zip(aList, bList) #返回zip对象
cList
<zip object at 0x0000000003728908>
list(cList) #把zip对象转换成列表
[(1, 4), (2, 5), (3, 6)]


for item in enumerate('abcdef'):
print(item)
# 输出结果
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')

元组

简述

tuple一旦初始化就不能修改,这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。

tuple的陷阱:当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来。

只有1个元素的tuple定义时必须加一个逗号,来消除歧义,以免你误解成数学计算意义上的括号。

tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。

字典

字典元素的读取

使用字典对象的items()方法可以返回字典的元素。
使用字典对象的keys()方法可以返回字典的“键”。
使用字典对象的values()方法可以返回字典的“值”。

Python知识点(四) 选择与循环

例3-7 输出所有3位“水仙花数”。所谓n位水仙花数是指1个n位的十进制数,其各位数字的n次方之和等于该数本身。例如:153是水仙花数,因为153 = 13 + 53 + 33 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for i in range(100, 1000):
bai, shi, ge = map(int, str(i))
if ge**3 + shi**3 + bai**3 == i:
print(i)

for num in range(100, 1000):
if sum(map(lambda x:int(x)**3, str(num))) == num:
print(num)

# 扩展到n位水仙花数:
n = int(input('请输入位数:'))
for num in range(10**(n-1), 10**n):
if sum(map(lambda i: int(i)**n, str(num))) == num:
print(num)

例3-12 鸡兔同笼问题。假设共有鸡、兔30只,脚90只,求鸡、兔各有多少只。

1
2
3
4
for ji in range(0, 31):
if 2*ji + (30-ji)*4 == 90:
print('ji:', ji, ' tu:', 30-ji)
break

例3-17 计算前n个自然数的阶乘之和1!+2!+3!+…+n!的值。

1
2
3
4
5
6
7
8
9
def func3(n):
result = 0
t = 1
for i in range(1, n+1):
t = t * i
result = result+t
return result


Python知识点(五) 字符串与正则表达式

编码

  • python3默认的字符集是 unicode,也就是str 类型,包含了全世界所有的字符

  • unicode只是一种编码规范,是一个字符集。

  • UTF-8字符集比GBK字符集大很多,有些字符没有对应的GBK编码。

注:utf-8和gbk编码之间不能之间转换,要在unicode之间过个场才能转换。

字符串

str.lower() 或 str.upper()方法返回字符串的副本,全部字符小写/大写。

1
"AbCdEfGh".lower() # 结果为 "abcdefgh"

str.split(sep=None)方法返回一个列表,由str根据sep被分隔的字段组成。

1
"A,B,C".split(",")  # 结果为 ['A','B','C']

str.strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。

注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。默认是删除开头或结尾的空格。

1
"   Runoob    0090  ".strip()  # 去除首尾空格  输出结果Runoob    0090

str.count(sub)方法返回子串sub在str中出现的次数。

1
"an apple a day".count("a")  # 结果为 4

str.isalnum() 方法检测字符串是否由字母和数字组成。

注意:如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False

1
'abc'.isalnum()   #  结果为 True

str.replace(old, new)方法返回字符串str副本,所有old字符串都被替换为new字符串。

1
2
"python".replace("n","n123.io")  # 结果为 "python123.io"

str.center(width,[fillchar])根据宽度width显示居中字符串,fillchar可选。

1
"python".center(20,"=")  # 结果为  '=======python======='

str.join(iter)方法将在iter变量除最后元素外每个元素后增加一个str。

1
",".join("12345")  # 输出结果 "1,2,3,4,5" 

rstrip() 方法将删除 string 字符串末尾的指定字符,默认为空白符,包括空格、换行符、回车符、制表符。

1
('welcome,'*3).rstrip(',')+'!'   # 输出结果  'welcome,welcome,welcome!'

Python知识点(六) 面向对象程序设计

私有成员,只有类对象自己能访问,子类对象不能直接访问这个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。

注意:Python中不存在严格意义上的私有成员。

Python知识点(七) 异常处理

try…except…finally结构

1
2
3
4
5
6
7
8
9
10
11
12
try:
<语句块1> # 需要检测异常的代码块
#无异常,忽略except语句块
except <异常名称1>:
<语句块2> # 引发了异常名称1时执行语句块2
[except <异常名称2>:
<语句块3>] # 引发了异常名称2时执行语句块3
[else:
<语句块4>] # 无异常发生时执行的语句块
[finally: #关闭文件等后事处理,有无异常都执行
<语句块5>]

断言与上下文管理

断言语句的语法是:assert expression[, reason]

当判断表达式expression为真时,什么都不做;如果表达式为假,则抛出异常。

上下文管理语句:使用with自动关闭资源,可以在代码块执行完毕后还原进入该代码块时的现场。不论何种原因跳出with块,不论是否发生异常,总能保证文件被正确关闭,资源被正确释放。

Python知识点(八) 注意点

  1. python没有三元表达式,但有类似的语法表达方式:
1
2
3
4
result = x if condition else y

# 还可以这样写
result = (x, y)[condition]