记录一些知识点、示例以及在学习中深入了解的地方。
主要运算符: 算术运算符、赋值运算符、比较运算符、逻辑运算符、条件运算符(if-else, 详见条件语句)、位运算符(详见位运算)
# 【示例】
a = 1
a = a+5
# 运行结果
# Out: 6
a = 1
a +=5 # 等同于a=a+5
# 运行结果
# Out: 11
a -=5 # 等同于a=a-5
# Out: 6
a *=5 # 等同于a=a*5
# Out: 30
a **=2 # 等同于a=a**2
# Out: 900
a /=9 # 等同于a=a/9
# Out: 100.0 #注意:除法后,整型会变成浮点型
a //= 5 # 等同于a=a//5
# Out: 20.0 # 因为之前a已经变为浮点数了, 所以此处结果为浮点数
a %= 6 # 等同于a=a%6
# Out: 2
#【示例】
a = 10>20 # 相当于a=False
b = 10>=10 # 相当于b=True
c = 10!=10 # 相当于c=False
d = 2 >True # 相当于d=True
#【示例】
a = '2' >'1' #True
b = '2' >'11' #True
c = 'a' >'b' #False
d = 'ab' <'ac' #True
#【示例】
temp = 1<2<3 #True
# 相当于表达式:2>1 and 2<3
# 不是:1<2 and 1<3
temp = 1<4<3 #False
# 相当于表达式:4>1 and 4<3
# 不是:1<4 and 1<3
如果相比较两个对象是否是同一个对象,用is/is not. (详见1.2)
#【示例-not】
a = 0
a = not a
print (a) #True
b = 1
b = not b
print (b) #False
print (type(b)) #
c = 'hello'
c = not c
print (c) #False
#【示例-and】
result = True and True
print (result) #True
result = True and False and False
print (result) #False
#【示例-or】
result = True or True
print (result) #True
result = True or False or False
print (result) #True
result = False or False
print (result) #False
#【证明and是短运算】
True and print("猜猜我出来么") #返回:猜猜我出来么
False and print("猜猜我出来么") #没有任何返回
#【证明or是短运算】
True or print("猜猜我出来么") #没有任何返回
False or print("猜猜我出来么") #返回:猜猜我出来么
#【非布尔值的逻辑运算】
a = 1 and []
print (a) #[] 相当于True and False, 所以返回False,False对应的是第二个值[]
b = "abc" and 'cde'
print (b) #'cde' 相当于True and True,因为第一个值的布尔值为True, 所以对第二个值进行比较,也是True, 返回第二个值"cde"。
c = 0 and []
print(c) #0 相当于False and False, 因为第一个值的布尔值为False, 所以不会对第二个值进行比较,直接返回第一个值0。
d = "abc" or None or 'cde'
print (d) # "abc"
e = 0 or None
print (e) # None
is, is not 对比的是两个变量的内存地址(id),即比较两个对象是否为同一对象;==, != 对比的是两个变量的值。
如果比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的。
如果对比的两个变量,指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。
#【is和==的区别】
a = 1
print ("hello ") if a == True else print("world") #hello
print ("hello ") if a is True else print("world") #world
#示例1:均为不可变类型
a = "hello"
b = "hello" # 变量a,b指向了不可变对象
print ('a_id =', id(a))
print ('b_id =', id(b))
# 运行结果 指向不可变对象的变量id相同说明a,b都指向了同一个对象
# a_id = 2604572449456
# b_id = 2604572449456
print(a is b, a == b)
# 运行结果
# True True
#示例2:均为可变类型
a = ["hello"]
b = ["hello"] # 变量a,b指向了可变对象
print ('a_id =', id(a))
print('b_id =', id(b))
# 运行结果 两个可变对象的id不同说明变量a和b分别指向了不同的对象,尽管这两个对象的值相同,但它们在内存里存储的位置不同。
# a_id = 2604572258880
# b_id = 2604572251648
print(a is b, a == b)
# 运行结果
# False True, 因为两个可变对象的地址不完全一样
一般,算术运算符>位运算符>比较运算符>逻辑运算符
对于算术运算符,python中的优先级与数学中的优先级一致,幂最优先,然后乘除,再后加减。
对于逻辑运算符,优先级:not > and > or
#【逻辑运算符优先级比较】
a = 1 or 2 and 3
print (a) #1
#如果and优先级高,先比较2和3,返回3,然后比较1和3,返回1。
#如果or优先级高或者两个运算符优先级一致(即从左向右依次运算)的话,则会先比较1和2, 返回1,然后比较1和3,返回3
运算符的优先级可以在官方文档的表格(python 3.8)中查找,在表格中越靠下的运算符优先级越高。
Python 里万物皆对象(object),数据类型也是一种对象,对象都有相应的属性 (attributes) 和方法(methods)。
变量与对象的关系: 变量里存储的不是对象的值,而是对象的id,即对象的内存地址。
属性和运算符在一起的时候,注意分清是哪个对象的属性。先属性,再运算符。
#【示例】
b=18
c=~b
print(bin(b^c)) #-0b1
print (b^c.bit_length()) #bit.length是c的属性,结果为23
print ((b^c).bit_length()) #bit.length是(b^c)的属性,结果为1
具体见下一篇文章 Python 训练营Day2 - 数据结构
整型 int:
python是一个动态类型的语言。python中的整数大小没有限制,不会超范围溢出
如果数字过大,可以用下划线做分隔符
#【示例】
a = 123_456_789
print (a) #123456789
#打印数据类型
print (type(a)) #
print (type("a")) #
浮点型float:
对浮点型进行计算的时候可能会得到不太精确的结果,因为计算机里是按二进制存储计算的。所以在对精度很高的计算中(如金融),不建议用浮点数直接计算。
#【示例】
a = 0.1+0.2
b = 0.1+0.3
print (a) #0.30000000000000004
print (b) #0.4
#打印数据类型
print (type(a)) #
想保留浮点型的小数点后 n 位,可以用 decimal 包(package)里的 Decimal 对象和 getcontext() 方法来实现。
getcontext() 显示Decimal 对象的默认精度值是 28 位,可以用 getcontext().prec 来调整精度。
注意,在getcontext().prec 语句后运算,调整精度才生效。
#【示例】
from decimal import Decimal
a = Decimal(0.1)+Decimal(0.3)
b = Decimal(0.1+0.3)
m = Decimal(0.1) / Decimal(0.3)
n = 0.1 / 0.3
print (a) #0.3999999999999999944488848769
print (b) #0.40000000000000002220446049250313080847263336181640625
print (m) #0.3333333333333333641728617951
print (n) #0.33333333333333337
decimal.getcontext().prec = 4
print (a) #0.3999999999999999944488848769
print (b) #0.40000000000000002220446049250313080847263336181640625
a = Decimal(0.1)+Decimal(0.3)
b = Decimal (0.1+0.3)
m = Decimal(0.1)/Decimal(0.3)
n = 0.1/0.3
print (a) #0.4000
print (b) #0.40000000000000002220446049250313080847263336181640625
print (m) #0.3333
print (Decimal(n)) #0.33333333333333337034076748750521801412105560302734375
布尔值:只有两个值,True和False,主要用于进行逻辑判断。实质上是整型,True即1,False即0
#【示例】
a = True #打印的时候不要带引号,不然就变成字符串了
a_1 = "True"
b = False
print (a, b) #True False
#打印布尔值的数据类型
print (type (a)) #
print (1+a) #2,说明布尔型实质上是整型,True数值为1
print (a+a_1) #TypeError: unsupported operand type(s) for +: 'bool' and 'str' ,因为布尔型和字符串不是一种数据类型,不能相加。
用bool(X)创建变量
X可以是:
#【字符转换为布尔值-示例】
m = ''
a = m is False
b = bool(m) is False
print (a, b, sep = ',') #False, True
空值(None):用于表示不存在
#【示例】
empty = None
print (empty) #None
#打印空值的数据类型
print (type (empty)) #
type()
不认为子类是一种父类类型,不考虑继承关系。isinstance()
认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()
。
print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)
#【示例】
student_1 = ['female','26','tall']
for i in student_1:
print('she',i,sep=' is ',end=' and ')
print('hello')
# 运行结果
# she is female and she is 26 and she is tall and hello
二进制有三种不同的表示形式:原码、反码和补码。
计算机内部使用补码表示二进制
为什么?为便于用加法器计算减法(所以用反码,类似3-5=3+[-5]),同时避免出现数字0出现两个编码(所以用补码,即反码+1,并且在计算机世界里设定0是正数)。
具体参见“为什么用补码”:https://zhuanlan.zhihu.com/p/105917577
范围:
示例:
00 00 10 11 #11
11<< 2
00 10 11 00 #44
示例:
00 00 10 11 #11
11>> 2
00 00 00 10 #2
‘
n << 1 -> 计算 n*2(注意结果的type)
n >> 1 -> 计算 n/2,负奇数的运算不可用
#【示例】
print(12/2) #6.0
print(12>>1) #6
n << m -> 计算 n*(2^m),即乘以 2 的 m 次方
#【示例】
print(12*2**3) #96
print(12<<3) #96
n >> m -> 计算 n/(2^m),即除以 2 的 m 次方(注意取整问题)
#【示例】
print(12/(2**3)) #1.5
print(12>>3) #1
1 << n -> 2^n
#【示例】
print(2**6) #64
print(1<<6) #64
print(2**3.5) #11.313708498984761
print(1<<3.5) #TypeError:: unsupported operand type(s) for <<: 'int' and 'float',即必须是整数
交换a和b: a ^= b, b ^= a, a ^= b
推导(使用交换律):
a ^= b -> a = a ^ b
b ^= a -> b = b ^ a = b ^ a ^ b=a
a ^= b -> a = a ^ b = (a ^ b) ^ (b ^ a ^ b) = a ^ b ^ a = b
#【示例-通过^快速交换两个整数】
a=3
b=5
a^=b
print (a) #6
print (b) #5
b^=a
print (a) #6
print (b) #3
a^=b
print (a) #5
print (b) #3
5 & (-5)= 00 00 01 01 & 11 11 10 11 = 00 00 00 01 = 1
14 & (-14)= 00 00 11 10 & 11 11 00 10 = 00 00 00 10 = 2
最后为1的位置后面均为0,例如:原数a=10000,-a = 01111(反码),-a=10000(补码)
二进制:0b开头, 01
八进制:0o开头, 01234567
十六进制:0x开头, 0123456789abcdef
python中bin()一个十进制的负数,输出的是二进制原码表示加上负号(与负数在python内部的存储形式不同)
#【示例-python中print一个二进制正数】
a = 16
print (bin(a)) #0b10000
print(bin(-a)) #-0b10000
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
python的流程控制语句分成两大类:条件判断语句和循环语句。
if语句、if-else语句、if-elif-else语句
if 条件表达式: #先对条件表达式进行判断
语句 #如果条件表达式为True,执行语句;如果条件表达式为False,不执行语句。
单个 if 语句中的 expression 条件表达式可以通过布尔操作符 and,or和not 实现多重条件判断,例如:if 2>1 and not 2>3
if 条件表达式:#先对条件表达式进行判断
语句1 #若条件表达式为True,执行语句1
else:
语句2 #若条件表达式为False,执行else里的语句2
#【示例-用if-else实现返回最大值-推导式写法】
a = 0
b = 1
max = a if a>b else b
print (max) #1
if 条件表达式1:#先对条件表达式1进行判断
语句1 #若条件表达式为True,执行语句1
elif 条件表达式2: #若条件表达式1为False,对elif里的条件表达式2进行判断
语句2 #若条件表达式2为True,执行elif里的语句2
else:
语句3 #若条件表达式2为False,执行else里的语句3
# 普通写法
if 条件甲:
结果甲
elif 条件乙:
结果乙
else 结果丙
# 推导式写法(用一连串的if-else)
结果甲 if 条件甲 else 结果乙 if 条件乙 else 结果丙
# 把结果写在if之前,把该结果对应的条件写在if之后
#【if-elif-else 推导式写法】
a = 0
b = 1
c = 3
max_num = a if a>b and a>c else b if b>c else c
print (max_num) #3
当assert关键词后边的条件为 False 时,程序自动崩溃并抛出AssertionError的异常。可以用来在程序中置入检查点,只有条件为 True 才能让程序正常工作。
#【示例】
my_list = ['lsgogroup','0',12]
i = 3
assert i<len(my_list)
my_list.pop(i) # AssertionError
循环语句用于使指定的代码块重复指定的次数。
循环语句分为两种: while循环,for循环
while 条件表达式:
代码块
while循环执行流程:
while循环的三个要素:
【while循环示例】
#【while循环示例】
i = 0
while i < 5:
print ('hello',i)
i +=1
#结果
#hello 0
#hello 1
#hello 2
#hello 3
#hello 4
【while循环-打印一个矩阵】
#【while循环示例】
#打印一个矩阵
string = [1,1,1,1,1,0]
lenth = len(string)
while lenth:
print(string)
temp = string[0]
string = string[1:]
string.append(temp)
lenth = lenth-1
#print (lenth)
#结果:
#[1, 1, 1, 1, 1, 0]
#[1, 1, 1, 1, 0, 1]
#[1, 1, 1, 0, 1, 1]
#[1, 1, 0, 1, 1, 1]
#[1, 0, 1, 1, 1, 1]
#[0, 1, 1, 1, 1, 1]
while 条件表达式:
代码块
else:
代码块
当while循环正常执行完的情况下,执行else输出,如果while循环中执行了跳出循环的语句,比如 break,将不执行else代码块的内容。
【while-else循环示例】
#【while循环示例】
i = 0
while i < 5:
print ('hello',i)
i +=1
else:
print ('bye')
#结果
#hello 0
#hello 1
#hello 2
#hello 3
#hello 4
#bye
range([start,] stop[, step=1])
range生成一个从start参数的值开始到stop参数的值结束的数字序列,该序列包含start的值但不包含stop的值。
#【示例】
for i in range(2, 5): # 不包含5, step默认为1
print(i)
# 2
# 3
# 4
#【示例】
for i in range(1, 5, 2): # 每隔一个数输出
print(i)
# 1
# 3
enumerate(sequence, [start=0])
#【示例1】
m = enumerate(['A','B','C','D'])
print(type(m))
print(m) #不能直接print
print(list(m)) #变成列表类型输出
#
#
#[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]
#【示例2】
m = ['A','B','C','D']
print( name for name in enumerate(m)) #需要两个参数,第一个参数表示序号
print( (i,name) for i,name in enumerate(m)) #不能直接打印
print( tuple((i,name) for i,name in enumerate(m))) #按元组类型输出
print( list((i,name) for i,name in enumerate(m))) #按列表类型输出
# at 0x0000021C76859CF0>
# at 0x0000021C76859CF0>
#((0, 'A'), (1, 'B'), (2, 'C'), (3, 'D'))
#[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]
break: 跳出当前所在层的循环
#【示例】
i = 0
while i < 5:
if i == 2:
break
print (i)
i += 1
#【运行结果】
#0
#1
#【示例2】
i = 0
while i < 5:
# if i == 2:
# break
print (i)
i += 1
else:
print ('The End')
# 运行结果
#0
#1
#2
#3
#4
#The End
#【示例3】
i = 0
while i < 5:
if i == 2:
break
print (i)
i += 1
else:
print ('The End')
# 运行结果
#0
#1
continue:结束本轮循环并开始下一轮循环,即不再执行本轮循环continue之后的语句,并开始执行下一轮循环(注意!还在当前层的循环里)。
#【示例-continue】
i = 0
while i < 5:
i += 1
if i == 3:
continue
print (i)
# 运行结果
#1
#2
#4
#【示例-continue错误用法】
i = 0
while i < 5:
if i == 3:
continue
print (i)
i += 1 #当i==3以后,这个语句因为在continue之后,所以不再被执行,导致程序进入死循环
# 运行结果
#0
#1
#2
#*** (死循环)
pass: 不做任何事”,如果你在需要有语句的地方不写任何语句,那么解释器会提示出错,而 pass 语句就是用来解决这些问题的。
#【示例-pass】
i = 0
while i < 5:
# 运行结果
# 死循环,因为i一直小于5
i = 0
while i < 5:
pass
# 运行结果
# 通过,无任何返回或报错
i = 0
if i < 1:
# 运行结果
# 系统报错 SyntaxError: unexpected EOF while parsing
i = 0
if i < 1:
pass
# 运行结果
# 通过,无任何返回或报错
a. 列表推导式: [ expr for value in collection [if condition] ]
b. 元组推导式: ( expr for value in collection [if condition] )
c. 字典推导式:{ key_expr: value_expr for value in collection [if condition] }
d. 集合推导式:{ expr for value in collection [if condition] }
e. 其他推导式:next(iterator[, default]) Return the next item from the iterator. If default is given and the iterator is exhausted, it is returned instead of raising StopIteration.