02 python初识数据类型和数据运算符
1、初识数据类型
1.1、数字
1、整数
- Python2中有int和long,但能自动转换。
- Python3中只有int。
(1)int(整型)
- 在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647。
- 在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807。
(2)long(长整型)
- 跟C语言不同,Python的长整数没有指定位宽,即:Python没有限制长整数数值的大小,但实际上由于机器内存有限,我们使用的长整数数值不可能无限大。
- 注意,自从Python2.2起,如果整数发生溢出,Python会自动将整数数据转换为长整数,所以如今在长整数数据后面不加字母L也不会导致严重后果了。
2、浮点数(float)
- 浮点数用来处理实数,即带有小数的数字。类似于C语言中的double类型,占8个字节(64位),其中52位表示底,11位表示指数,剩下的一位表示符号。
3、Bytes类型
- Python2不区分二进制字节和字符串,二者可以拼接
- Python3区分二进制字节和字符串,二者不可以拼接
转换:
string--(encode(‘string的编码’))-->bytes
bytes--(decode(‘string的编码’))-->string
4、复数(complex)
- 复数由实数部分和虚数部分组成,一般形式为x+yj,其中的x是复数的实数部分,y是复数的虚数部分,这里的x和y都是实数。
5、十六进制数、八进制数、二进制数和十进制
- 十六进制:0x。十六机制转二进制,一位变四位。
- 八进制:0o。八机制转二进制,一位变三位。
- 二进制:0b。二进制转八进制,三位变一位;二进制转十六进制,四位变一位。
- 负十进制数转二进制数(以-5为例)
(1)正十进制转二进制 #5 --> 0000 0101
(2)按位取反 #0000 0101 --> 1111 1010
(3)末位加一 #1111 1010 + 0000 0001 --> 1111 1011
>>> print(int(0b1111)) #二进制转十进制 15 >>> print(int(0o1111)) #八进制转十进制 585 >>> print(int(0x1111)) #十六进制转十进制 4369 >>> print(int(1111)) #十进制 1111
1.2、布尔值
- 被解释器视为假的值:False、None、0、""、()、[]、{}。即标准值False和None、各种类型(包括浮点数、复数等)的数值0、空序列(如空字符串、空元组和空列表)以及空映射(如空字典)都被视为假。
- 被解释器视为真的值:其他非假的值(非假即真),包括特殊值True。
- True和False是0和1的别名,虽然看起来不同,但作用是相同的。
>>> True True >>> False False >>> True == 1 True >>> False == 0 True >>> True + False + 42 43
- 布尔值True和False属于类型bool
>>> bool('I think, therefore I am') True >>> bool(42) True >>> bool('') False >>> bool(0) False
1.3、序列和字典
容器:
- 序列:(如列表和元组)在序列中,每个元素都有编号
- 列表:可以修改的序列
- 元组: 不可以修改的序列
- 字符串:不可以修改的序列
- 映射:(如字典)在映射中,每个元素都有名称(也叫键)
Python中三种最重要的数据类型:列表、字符串和字典。
2、数据运算符
2.1、算术运算符
1、算数运算符
- 加法运算(+)
>>> a = 9 >>> b = 2 >>> print(a + b) #加号两边是int型,python解释器进行算数运算。 11 >>> a_str = 'mai' >>> b_str = 'heng' >>> print(a_str + b_str) #加号两边是str型,python进行字符串拼接。 maiheng >>> print(a + a_str) #加号两边的数据类型要一致,否则返回异常 Traceback (most recent call last): File "<pyshell#17>", line 1, in <module> print(a + a_str) TypeError: unsupported operand type(s) for +: 'int' and 'str'
- 减法运算
>>> print(a - b) 7
- 乘法运算
>>> print(a * b) 18
- 除法运算
>>> print(a / b) 4.5
2、扩展的算术运算符
- 乘方(求幂)运算符
>>> print(a ** b) #请注意,乘方运算符的优先级比求负(单目减)高 81
- 整除运算符
>>> print(a // b) #对于整除运算,需要明白的一个重点是它向下圆整结果 4
- %:求余(求模)运算符
>>> print(a % b) 1
2.2、赋值运算符
![](https://img2020.cnblogs.com/blog/2270526/202101/2270526-20210109001240618-1892080994.png)
- 赋值运算符
>>> a = 9 >>> print('a = {}\ta_id:{}'.format(a,id(a))) a = 9 a_id:140709872994224 >>> b = a #变量赋值变量,是两个变量使用同一个内存引用,即使用同一个内存地址 >>> print('a = {}\ta_id:{}\nb = {}\tb_id:{}'.format(a,id(a),b,id(b))) a = 9 a_id:140709872994224 b = 9 b_id:140709872994224 >>> a = 4 #重新赋不同的值,将使用新的内存空间 >>> print('a = {}\ta_id:{}\nb = {}\tb_id:{}'.format(a,id(a),b,id(b))) a = 4 a_id:140709872994064 b = 9 b_id:140709872994224
- 其他赋值运算符
>>> a_str='mai' >>> a_str += 'heng' #相当于a_str = a_str + 'heng',只有+=支持字符串拼接 >>> print(a_str) maiheng >>> num = 9 >>> num += 2 #相当于num = num + 2 >>> print(num) 11 >>> num = 9 >>> num -= 2 #相当于num = num - 2 >>> print(num) 7 >>> num = 9 >>> num *= 2 #相当于num = num * 2 >>> print(num) 18 >>> num = 9 >>> num /= 2 #相当于num = num / 2 >>> print(num) 4.5 >>> num = 9 >>> num **= 2 #相当于num = num ** 2 >>> print(num) 81 >>> num = 9 >>> num %= 2 #相当于num = num % 2 >>> print(num) 1 >>> num = 9 >>> num //= 2 #相当于num = num // 2 >>> print(num) 4
2.3、比较运算符
- 比较运算符比较的是两个对象的值
>>> m1 = 'hello' >>> m2 = 'hello' >>> result = m1 == m2 #这里使用的是字符串作比较,当然数字也没问题 >>> print(result) True >>> result = m1 != m2 >>> print(result) False >>> result = m1 > m2 >>> print(result) False >>> result = m1 < m2 >>> print(result) False >>> result = m1 >= m2 >>> print(result) True >>> result = m1 <= m2 >>> print(result) True
2.4、身份运算符
- 身份运算符比较的是两个对象的引用,即内存地址。
- ==用来检查两个对象的值是否相等,而is用来检查两个对象是否相同(是同一个对象)。
- 不要将is用于数和字符串等不可变的基本值。鉴于Python在内部处理这些对象的方式,这样做的结果是不可预测的。
>>> x = y = [1, 2, 3] >>> z = [1, 2, 3] >>> print('x == y:%s, x_id:%s, y_id:%s' %(x == y,id(x),id(y))) x == y:True, x_id:2193461117568, y_id:2193461117568 >>> print('x == z:%s, x_id:%s, z_id:%s' %(x == z,id(x),id(z))) x == z:True, x_id:2193461117568, z_id:2193479884352 >>> print('x is y:%s, x_id:%s, y_id:%s' %(x is y,id(x),id(y))) x is y:True, x_id:2193461117568, y_id:2193461117568 >>> print('x is z:%s, x_id:%s, z_id:%s' %(x is z,id(x),id(z))) x is z:False, x_id:2193461117568, z_id:2193479884352
- 字符串和序列的比较
- 不要将is用于数和字符串等不可变的基本值
>>> "alpha" < "beta" #字符串是根据字符的字母排列顺序进行比较的,先转换为数字在比较 True >>> ord('a') #字符转换为ASCII码 97 >>> chr(97) #ASCII码转换为字符 'a' >>> [2, [1, 4]] < [2, [1, 5]] #序列也是按顺序比较的 True
1、python的小整数对象池
(1)小整数对象池- 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池,避免为整数频繁申请和销毁内存空间。
- Python对小整数的定义是[-5, 256]。这些整数对象是提前建立好的,不会被垃圾回收。在一个Python的程序中,无论这些整数处于LEGB中的哪个位置使用的都是同一个对象。
>>> a1 = 256 >>> b1 = 256 >>> print('a1 is b1是{},\ta1={},\tb1={},\ta1_id是{},\tb1_id是{}'.format(a1 is b1,a1,b1,id(a1),id(b1))) #结果是True a1 is b1是True, a1=256, b1=256, a1_id是140709980939920, b1_id是140709980939920 >>> a2 = 257 >>> b2 = 257 >>> print('a2 is b2是{},\ta2={},\tb2={},\ta2_id是{},\tb2_id是{}'.format(a2 is b2,a2,b2,id(a2),id(b2))) #结果是False a2 is b2是False, a2=257, b2=257, a2_id是2512877094768, b2_id是2512877094608
(2)LEGB
- Python 由很多名字空间,而 LEGB 则是名字空间的一种查找规则。
- LEGB 代表名字查找顺序: locals --> enclosing function --> globals --> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间
2、python的大整数对象池。
- python shell是每次执行一次,所以每次的大整数都重新创建,即开辟新的内存空间。
- 在pycharm(即在.py文件)中,每次运行是所有代码都加载都内存中,属于一个整体,所以这个时候会有一个大整数对象池,即处于一个代码块的大整数是同一个对象。
a1 = 256 #在Pycharm中 b1 = 256 print('a1 is b1是{},\ta1={},\tb1={},\ta1_id是{},\tb1_id是{}'.format(a1 is b1,a1,b1,id(a1),id(b1))) #结果是True a2 = 257 b2 = 257 print('a2 is b2是{},\ta2={},\tb2={},\ta2_id是{},\tb2_id是{}'.format(a2 is b2,a2,b2,id(a2),id(b2))) #结果是True <<< a1 is b1是True, a1=256, b1=256, a1_id是140709980939920, b1_id是140709980939920 a2 is b2是True, a2=257, b2=257, a2_id是2170728401904, b2_id是2170728401904
3、python中字符串的intern机制
- 在python shell中,仅仅包括下划线、数字、字母的字符串才会采用intern机制。
- 在早期的python中,字符串且不能超过20个字符。因为如果超过20个字符,解释器认为这个字符串不常用,不用放入字符串池中。
>>> a1 = 'a' >>> b1 = 'b' >>> print('a1 is b1是{},\ta1={},\tb1={},\ta1_id是{},\tb1_id是{}'.format(a1 is b1,a1,b1,id(a1),id(b1))) a1 is b1是False, a1=a, b1=b, a1_id是2038762110456, b1_id是2038762108776 >>> a2 = 'a' * 20 >>> b2 = 'a' * 20 >>> print('a2 is b2是{},\ta2={},\tb2={},\ta2_id是{},\tb2_id是{}'.format(a2 is b2,a2,b2,id(a2),id(b2))) a2 is b2是True, a2=aaaaaaaaaaaaaaaaaaaa, b2=aaaaaaaaaaaaaaaaaaaa, a2_id是2038771554536, b2_id是2038771554536 ###Python 2.7.18 Shell >>> a3 = 'a' * 21 >>> b3 = 'a' * 21 >>> print('a3 is b3是{},\ta3={},\tb3={},\ta3_id是{},\tb3_id是{}'.format(a3 is b3,a3,b3,id(a3),id(b3))) a3 is b3是False, a3=aaaaaaaaaaaaaaaaaaaaa, b3=aaaaaaaaaaaaaaaaaaaaa, a3_id是56246896, b3_id是64983536 ###Python 3.6.5 Shell >>> a3 = 'a' * 21 >>> b3 = 'a' * 21 >>> print('a3 is b3是{},\ta3={},\tb3={},\ta3_id是{},\tb3_id是{}'.format(a3 is b3,a3,b3,id(a3),id(b3))) a3 is b3是False, a3=aaaaaaaaaaaaaaaaaaaaa, b3=aaaaaaaaaaaaaaaaaaaaa, a3_id是2038771554752, b3_id是2038771554536 ###Python 3.7.7 Shell >>> a3 = 'a' * 21 >>> b3 = 'a' * 21 >>> print('a3 is b3是{},\ta3={},\tb3={},\ta3_id是{},\tb3_id是{}'.format(a3 is b3,a3,b3,id(a3),id(b3))) a3 is b3是True, a3=aaaaaaaaaaaaaaaaaaaaa, b3=aaaaaaaaaaaaaaaaaaaaa, a3_id是2462280528480, b3_id是2462280528480 ###Python 3.8.7 Shell >>> a3 = 'a' * 21 >>> b3 = 'a' * 21 >>> print('a3 is b3是{},\ta3={},\tb3={},\ta3_id是{},\tb3_id是{}'.format(a3 is b3,a3,b3,id(a3),id(b3))) a3 is b3是True, a3=aaaaaaaaaaaaaaaaaaaaa, b3=aaaaaaaaaaaaaaaaaaaaa, a3_id是2304345552096, b3_id是2304345552096
2.5、成员运算符
name = input('What is your name?') if 's' in name: print('Your name contains the letter "s".') else: print('Your name does not contain the letter "s".')
2.6、逻辑运算符
- 短路逻辑:
- 在表达式x and y中,仅当x和y都为真时表达式才为真。因此如果x为假,表达式立即返回假(即返回x),而不关心y。
- 在表达式x or y中,一真则真。因此如果x为真,就返回x,否则返回y。
-
and要碰假,返回第一个假,否则返回最后一个真(遇假则停)
or 要碰真,返回第一个真,否则返回最后一个假(遇真则停)
>>> print(1 < 2 and 2 < 3) #逻辑运算符and,一假即假 True >>> print(1 > 2 and 2 < 3) False >>> print(1 < 2 and 2 > 3) False >>> print(1 > 2 and 2 > 3) False >>> print(1 < 2 or 2 < 3) #逻辑运算符or,一真即真 True >>> print(1 > 2 or 2 < 3) True >>> print(1 < 2 or 2 > 3) True >>> print(1 > 2 or 2 > 3) False >>> print(1 > 2) #逻辑运算符not False >>> print(not 1 > 2) True
2.7、位运算符
![](https://img2020.cnblogs.com/blog/2270526/202101/2270526-20210109015754871-334300438.png)
>>> print('60 & 13:{}, 60的二进制:{}, 13的二进制:{}'.format(60 & 13,bin(60),bin(13))) #按位与,双一为一 60 & 13:12, 60的二进制:0b111100, 13的二进制:0b1101 >>> print('60 | 13:{}, 60的二进制:{}, 13的二进制:{}'.format(60 | 13,bin(60),bin(13))) #按位或,有一为一 60 | 13:61, 60的二进制:0b111100, 13的二进制:0b1101 >>> print('60 ^ 13:{}, 60的二进制:{}, 13的二进制:{}'.format(60 ^ 13,bin(60),bin(13))) #按位异或,不同为一 60 ^ 13:49, 60的二进制:0b111100, 13的二进制:0b1101 >>> print('60 << 2:{}, 60的二进制:{}, 60左移2为后的二进制:{}'.format(60 << 2,bin(60),bin(60 << 2))) #按位左移,n << m结果是n*(2**m) 60 << 2:240, 60的二进制:0b111100, 60左移2为后的二进制:0b11110000 >>> print('60 >> 2:{}, 60的二进制:{}, 60右移2为后的二进制:{}'.format(60 >> 2,bin(60),bin(60 >> 2))) #按位右移,n >> m结果是n//(2**m) 60 >> 2:15, 60的二进制:0b111100, 60右移2为后的二进制:0b1111
3、运算符优先级
以下表格列出了从最高到最低优先级的所有运算符