天池Python训练营Day1 - 从变量到循环语句
Posted 文仙草
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天池Python训练营Day1 - 从变量到循环语句相关的知识,希望对你有一定的参考价值。
记录一些知识点、示例以及在学习中深入了解的地方。
从变量到循环语句
1、变量、运算符与数据类型
1.1 运算符
主要运算符: 算术运算符、赋值运算符、比较运算符、逻辑运算符、条件运算符(if-else, 详见条件语句)、位运算符(详见位运算)
1.1.1 常用运算符
- 算术运算符: +(加), -(减), *(乘), **(幂), /(除), // (整除,只取整数部分,不四舍五入), %(取模,即取余数)。 / (除法运算) 总会返回浮点类型; //(整除运算)会返回整型。
- 赋值运算符:= (将等号右侧的值赋值给左侧的变量),此外还有+=, -=, *=,**=, /=, //=, %=
注意:^是异或位运算符,不是幂运算符! 所以7^2 不等于49,而是等于5
# 【示例】
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 //= 6 # 等同于a=a//6
# Out: 16.0 # 因为之前a已经变为浮点数了, 所以此处结果为浮点数
a %= 6 # 等同于a=a%6
# Out: 2
除法运算符“/ ”和取整运算法“// ”比较
#在分母和分子都是整数的情况下,
#除法运算法结果为float,而取整运算符结果为int
type(6/2)
out: float
type(6//2)
out:int
type(6//5)
out: int
#在分母和分子至少一方为浮点数的情况下,两个运算符的结果均为float
type(6.0/2)
type(6/2.0)
type(6.0//2)
type(6//2.0)
#以上四项的结果均为float
- 比较运算符(关系运算符): 用于比较两个对象的值之间的关系,总会返回一个布尔值(True, False)。
- 关系运算符包括:>, <, >=, <=, !=(不等于), ==(等于)
#【示例】
a = 10>20 # 相当于a=False
b = 10>=10 # 相当于b=True
c = 10!=10 # 相当于c=False
d = 2 >True # 相当于d=True
- python支持对字符串进行比较,逐位比较字符unicode编码。但用运算符比较中文的意义不大,因为中文可能是按偏旁字首排序,也可能按笔画排序
#【示例】
a = '2' >'1' #True
b = '2' >'11' #True
c = 'a' >'b' #False
d = 'ab' <'ac' #True
- 可以连着使用关系运算符a<b<c, 表示的是中间值与前后两个值的比较,而不是第一个值与后面的值得比较。
#【示例】
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)
- 逻辑运算符: 用于做逻辑判断。
- 逻辑运算符包括:and(逻辑与), not(逻辑非), or(逻辑或)
- not逻辑非:对于布尔值,会对其进行取反操作;对于非布尔值,会先转换成布尔值,然后对其取反
#【示例-not】
a = 0
a = not a
print (a) #True
b = 1
b = not b
print (b) #False
print (type(b)) #<class 'bool'>
c = 'hello'
c = not c
print (c) #False
- and逻辑与:对符号两侧的值进行与运算。只要有一个值为False则返回False,只有所有的值都为True才返回True,所以可以理解为与运算为找False运算。
#【示例-and】
result = True and True
print (result) #True
result = True and False and False
print (result) #False
- or 逻辑或:对符号两侧的值进行或运算。只要有一个值为True则返回True,只有所有的值都为False才返回False,所以可以理解为与运算为找True运算
#【示例-or】
result = True or True
print (result) #True
result = True or False or False
print (result) #True
result = False or False
print (result) #False
- Python中,and(与运算)/or(或运算)均为短路的与运算,即如果找到了False/True,则不再对后面的值进行比较。
#【证明and是短运算】
True and print("猜猜我出来么") #返回:猜猜我出来么
False and print("猜猜我出来么") #没有任何返回
#【证明or是短运算】
True or print("猜猜我出来么") #没有任何返回
False or print("猜猜我出来么") #返回:猜猜我出来么
- 对于非布尔值的逻辑运算,Python会当做布尔值进行逻辑运算,然后返回原值。
#【非布尔值的逻辑运算】
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
1.1.2 is /is not (是或不是)的用法
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, 因为两个可变对象的地址不完全一样
1.1.3 运算符的优先级
一般,算术运算符>位运算符>比较运算符>逻辑运算符
对于算术运算符,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)中查找,在表格中越靠下的运算符优先级越高。
1.2 变量与对象
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
1.3 数据类型–字符串
具体见下一篇文章 Python 训练营Day2 - 数据结构
1.4 数据类型–整型、浮点数
整型 int:
python是一个动态类型的语言。python中的整数大小没有限制,不会超范围溢出
如果数字过大,可以用下划线做分隔符
#【示例】
a = 123_456_789
print (a) #123456789
#打印数据类型
print (type(a)) #<class 'int'>
print (type("a")) #<class 'str'>
浮点型float:
对浮点型进行计算的时候可能会得到不太精确的结果,因为计算机里是按二进制存储计算的。所以在对精度很高的计算中(如金融),不建议用浮点数直接计算。
#【示例】
a = 0.1+0.2
b = 0.1+0.3
print (a) #0.30000000000000004
print (b) #0.4
#打印数据类型
print (type(a)) #<class 'float'>
通过sys.float_info 查看系统中对浮点型数据的设置(比如取值范围)
# 查看系统中对浮点型数据的设置
sys.float_info
#结果
#sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
想保留浮点型的小数点后 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
1.5 数据类型–布尔值(bool)
布尔值:只有两个值,True和False,主要用于进行逻辑判断。实质上是整型,True即1,False即0
- int(True) = 1, int(False) = 0
- bool(1) = True, bool(0) = False
#【示例】
a = True #打印的时候不要带引号,不然就变成字符串了
a_1 = "True"
b = False
print (a, b) #True False
#打印布尔值的数据类型
print (type (a)) #<class 'bool'>
print (1+a) #2,说明布尔型实质上是整型,True数值为1
print (a+a_1) #TypeError: unsupported operand type(s) for +: 'bool' and 'str' ,因为布尔型和字符串不是一种数据类型,不能相加。
用bool(X)创建变量
X可以是:
- 基本类型:整型、浮点型、布尔型
如果X=0(整数0)或者0.0(浮点数0)为False,非0为True。 - 容器类型:字符串str(‘’)、元组tuple(())、列表list([])、字典dict()和集合set(set())
如果X为空变量(例如空列表[]),则bool(X)为False;X为非空变量,bool(X)为True。
#【字符转换为布尔值-示例】
m = ''
a = m is False
b = bool(m) is False
print (a, b, sep = ',') #False, True
1.6 数据类型–空值 None
空值(None):用于表示不存在
#【示例】
empty = None
print (empty) #None
#打印空值的数据类型
print (type (empty)) #<class 'NoneType'>
1.7 Type()和isinstance()的区别
type()
不认为子类是一种父类类型,不考虑继承关系。isinstance()
认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()
。
1.8 更改print()函数的默认值
print(*objects, sep=’ ‘, end=’\\n’, file=sys.stdout, flush=False)
- 关键字参数sep是实现分隔符,比如多个参数输出时想要输出中间的分隔字符;
- 关键字参数end是输出结束时的字符,默认是换行符\\n(即每次输出后都会换行);
- 关键字参数file是定义流输出的文件,可以是标准的系统输出sys.stdout,也可以重定义为别的文件;
- 关键字参数flush是立即把内容输出到流文件,不作缓存。
#【示例】
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
2、位运算
2.1 原码、反码和补码
二进制有三种不同的表示形式:原码、反码和补码。
- 原码:就是其二进制表示(注意,第一位是符号位)。
00 00 00 11 -> 3
10 00 00 11 -> -3 - 反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反(对应正数按位取反)。
00 00 00 11 -> 3
11 11 11 00 -> -3 - 补码:正数的补码就是原码,负数的补码是反码+1。
00 00 00 11 -> 3
11 11 11 01 -> -3 - 符号位:最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。
计算机内部使用补码表示二进制
为什么?为便于用加法器计算减法(所以用反码,类似3-5=3+[-5]),同时避免出现数字0出现两个编码(所以用补码,即反码+1,并且在计算机世界里设定0是正数)。
具体参见“为什么用补码”:https://zhuanlan.zhihu.com/p/105917577
范围:
- 0_1111111=+127 (补码)
- 0_0000000=+0 (补码)
- 1_1111111=-1 (补码)
- 1_0000000=-128 (补码)
2.2 按位操作
- 1)~(非): ~0 = 1,~1=0
- 2)&(与): 1&0=0,0&1=0, 0&0=0,1&1=1
- 3)|(或): 0|1=1, 1|0=1,0|0=0, 1|1=1
- 4)^ (异或): 0^1 = 1, 1^0=1, 0^0=0, 1^1=0 (两个对应位不同时为1
- 5)<<(左移): num<<i 将num的二进制表示向左移动i位所得的值;
- 6)>>(右移): num >> i 将num的二进制表示向右移动i位所得的值。
- 异或满足交换律和结合律:A^ B ^ A: = A ^ A ^ B = B
示例:
00 00 10 11 #11
11<< 2
00 10 11 00 #44
示例:
00 00 10 11 #11
11>> 2
00 00 00 10 #2
‘
2.3 利用位运算实现快速计算
2.3.1 通过 <<,>> 快速计算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',即必须是整数
2.3.2 通过 ^ 快速交换两个整数。
交换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
2.3.3 通过 a & (-a) 快速获取a的最后为 1 位置的整数.
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(补码)
2.3.4 python输出二进制
二进制:0b开头, 01
八进制:0o开头, 01234567
十六进制:0x开头, 0123456789abcdef
python中bin()一个十进制的负数,输出的是二进制原码表示加上负号(与负数在python内部的存储形式不同)
#【示例-python中print一个二进制正数】
a = 16
print (bin(a)) #0b10000
print(bin(-a)) #-0b10000
2.4 利用位运算实现整数集合
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
- 比如:集合a= 1, 3, 4, 8,可以表示成 01 00 01 10 10 而对应的位运算也就可以看作是对集合进行的操作。
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
- a | (1<<i) 表示 把 i 插入到集合a中,例如a|(1<<2)
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
- a & ~(1<<i) 表示 把 i 从集合a中删除,例如a&~(1<<3)
集合 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|
二进制 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
3、条件语句与循环语句
python的流程控制语句分成两大类:条件判断语句和循环语句。
3.1 条件语句 if-else
if语句、if-else语句、if-elif-else语句
3.1.1 if语句
if 条件表达式: #先对条件表达式进行判断
语句 #如果条件表达式为True,执行语句;如果条件表达式为False,不执行语句。
单个 if 语句中的 expression 条件表达式可以通过布尔操作符 and,or和not 实现多重条件判断,例如:if 2>1 and not 2>3
3.1.2 if-else语句
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
3.1.3 if-elif-else语句
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
3.1.4 assert关键词
当assert关键词后边的条件为 False 时,程序自动崩溃并抛出AssertionError的异常。可以用来在程序中置入检查点,只有条件为 True 才能让程序正常工作。
#【示例】
my_list = ['lsgogroup','0',12]
i = 3
assert i<len(my_list)
my_list.pop(i) # AssertionError
3.2 循环语句
循环语句用于使指定的代码块重复指定的次数。
循环语句分为两种: while循环,for循环
3.2.1 while循环
while 条件表达式:
代码块
while循环执行流程:
- 对布尔表达式进行求值判断;
- 如果表达式判断为True, 执行代码块;
- 代码块执行完毕后,再继续对表达式进行判断;
- 如果表达式判断为False, 跳出代码块;
- while循环的代码块会一直循环执行,直到表达式的值为False。
while循环的三个要素:
- 初始化表达式:初始化一个变量
- 条件表达式:设置与变量相关的循环条件
- 更新表达式:修改初始化变量的值,使得上述循环条件有可能为False
【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 以上是关于天池Python训练营Day1 - 从变量到循环语句的主要内容,如果未能解决你的问题,请参考以下文章