变量、运算符与数据类型
1.变量
变量是存储在内存中的值。在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。
- 变量的赋值:每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。等号(=)用来给变量赋值。
- 标准数据类型:
(1)Numbers(数字):
Python支持四种不同的数字类型:
int(有符号整型)
long(长整型[也可以代表八进制和十六进制])
float(浮点型)
complex(复数)
(2)String(字符串):
字符串或串(String)是由数字、字母、下划线组成的一串字符。
(3)List(列表):
列表用 [ ] 标识,是 python 最通用的复合数据类型。
(4)Tuple(元组):
元组用 () 标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。
(5)Dictionary(字典):
列表是有序的对象集合,字典是无序的对象集合。
两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。字典用"{ }"标识。字典由索引(key)和它对应的值value组成。
基本类型:整型、浮点型、布尔型
容器类型:字符串、元组、列表、字典和集合
确定bool(X) 的值是 True 还是 False,就看 X 是不是空,空的话就是 False,不空的话就是 True。
对于数值变量,0, 0.0 都可认为是空的。
对于容器变量,里面没元素就是空的。
dict = {}
dict['one'] = "This is one"
dict[2] = "This is two"
tinydict = {'name': 'runoob','code':6734, 'dept': 'sales'}
print dict['one'] # 输出键为'one' 的值
print dict[2] # 输出键为 2 的值
print tinydict # 输出完整的字典
print tinydict.keys() # 输出所有键
print tinydict.values() # 输出所有值
例子:找到一个整数的二进制表示,再返回其长度。
a = 1031
print(bin(a)) #0b10000000111
print(a.bit_length()) #11
有时候我们想保留浮点型的小数点后 n 位。可以用 decimal 包里的 Decimal 对象和 getcontext() 方法来实现。
import decimal
from decimal import Decimal
a = decimal.getcontext()
print(a)
# Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
# capitals=1,clamp=0,flags=[],
#traps=[InvalidOperation,DivisionByZero,Overflow])
b=Decimal(1)/Decimal(3)
print(b)
#0.3333333333333333333333333333
【例子】使 1/3 保留 4 位,用 getcontext().prec 来调整精度。
decimal.getcontext().prec = 4
c = Decimal(1) / Decimal(3)
print(c)
# 0.3333
2.运算符
2.1算术运算符:
运算符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
** | 幂 |
% | 取模:返回除法的余数 |
// | (向下)取整:返回商的整数部分 |
print(3//4) # 0
print(3%4) # 3
print(2**3) # 8
2.2 比较运算符:
2.3 赋值运算符:
2.4 位运算符:
a = 0011 1100
b = 0000 1101
-----------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011
运算符 | 描述 |
---|---|
& | 按位与 |
I | 按位或 |
^ | 按位异或,当两对应的二进位相异时结果为1 |
~ | 按位取反,~x 类似于 -x-1 |
<< | 左移 |
>> | 右移 |
print(bin(4))
# 0b100
print(bin(~4),~4)
# -0b101 -5
print(bin(4<<2),4<<2)
# 0b10000 16
print(bin(4>>2),4>>2)
# 0b1 1
2.5 逻辑运算符:
2.6 成员运算符:
2.7 身份运算符:
注意:
is,is not对比的是两个变量的内存地址==,!=对比的是两个变量的值比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not和==,=是完全等价的。
对比的两个变量,指向的是地址可变的类型(list,dict等),则两者是有区别的。
a = "hello"
b = "hello"
print(a is b, a==b) # True True
print(a is not b, a!=b) # False False
a = ["hello"]
b = ["hello"]
print(a is b, a==b) # False True
print(a is not b, a!=b) # True False
2.8 三元运算符
x, y=4, 5
if x<y:
small=x
else:
small=y
print(small) # 4
x, y=4, 5
small = x if x < y else y
print(small) # 4
2.8 运算符的优先级
一元运算符优于二元运算符。例如3**-2等价于3**(-2)。
先算术运算,后移位运算,最后位运算。例如1 << 3+2 & 7等价于1 << ((3+2)) & 7。
逻辑运算最后结合。例如3 < 4 and 4 < 5等价于(3 < 4) and (4 < 5)。
3.注释
在Python中,#表示注释,作用于整行。
单行注释:
#这是一个注释
多行注释:’’’’’'或者""""""表示区间注释,在三引号之间的所有内容被注释
'''
这是多行注释,用三个单引号
这是多行注释,用三个单引号
这是多行注释,用三个单引号
'''
4 其他
4.1 instance
判断一个对象是否是一个已知的类型 isinstance(object, classinfo)
print(isinstance(1,int) )#True
print(isinstance(5.2,float)) #True
print(isinstance(True,bool)) #True
print(isinstance('5.2',str)) #True
注:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
4.2 end参数
【例子】每次输出结束都用end设置的参数&结尾,并没有默认换行。\
shoplist=['apple','mango','carrot','banana']
print("This is printed with 'end='&''.")
for item in shoplist:
print(item,end='&')
print('hello world')
#This is printed with 'end='&''.
#apple&mango&carrot&banana&hello world
【例子】item值与’anotherstring’两个值之间用sep设置的参数&分割。由于end参数没有设置,因此默认是输出解释后换行,即end参数的默认值为\n。
shoplist=['apple','mango','carrot','banana']
print("This is printed with 'sep='&''.")
for item in shoplist:
print(item,'anotherstring',sep='&')
#This is printed with 'sep='&''.
#apple&anotherstring
#mango&anotherstring
#carrot&anotherstring
#banana&anotherstring
5.练习题
1.怎样对python中的代码进行注释?
在 Python 中,# 表示注释,作用于整行。
‘’’ ‘’’ 或者 “”" “”" 表示区间注释,在三引号之间的所有内容被注释。
2.python有哪些运算符,这些运算符的优先级是怎样的?
算术、比较、逻辑、位、三元运算符及其他运算符
运算符的优先级:
• 一元运算符优于二元运算符
• 先算术运算,后移位运算,最后位运算
• 逻辑运算最后结合
3.python 中 is, is not 与 ==, != 的区别是什么?
is, is not 对比的是两个变量的内存地址
==, != 对比的是两个变量的值
比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的。
对比的两个变量,指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。
4.python 中包含哪些数据类型?这些数据类型之间如何转换?
基本类型:整型、浮点型、布尔型
容器类型:字符串、元组、列表、字典和集合
转换为整型 int(x, base=10)
转换为字符串 str(object=’’)
转换为浮点型 float(x)
6.位运算
6.1 原码、反码和补码
原码:就是其二进制表示(注意,最高位是符号位)。
反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反。
00 00 00 11 -> 3
11 11 11 00 -> -3
补码:正数的补码就是原码,负数的补码是反码+1。
00 00 00 11 -> 3
11 11 11 01 -> -3
6.2 按位取反~
~ 把num的补码中的 0 和 1 全部取反(0 变为 1,1 变为 0)有符号整数的符号位在 ~ 运算中同样会取反。
6.3 按位与操作 &
只有两个对应位都为 1 时才为 1
00 00 01 01 -> 5
&
00 00 01 10 -> 6
---
00 00 01 00 -> 4
6.4 按位或操作 |
只要两个对应位中有一个 1 时就为 1
6.5 按位异或操作 ^
只有两个对应位不同时才为 1
A: 00 00 11 00
B: 00 00 01 11
A^B: 00 00 10 11
B^A: 00 00 10 11
A^A: 00 00 00 00
A^0: 00 00 11 00
A^B^A: = A^A^B = B = 00 00 01 11
6.6 按位左移操作 <<
num << i 将num的二进制表示向左移动i位所得的值。
00 00 10 11 -> 11
11 << 3
---
01 01 10 00 -> 88
6.7 按位右移操作 >>
num >> i 将num的二进制表示向右移动i位所得的值。
通过 <<,>> 快速计算2的倍数问题。
通过 ^ 快速交换两个整数。n << 1 -> 计算 n * 2
n >> 1 -> 计算 n / 2, 负奇数的预算不可用
n << m -> 计算 n * (2^m), 即乘以2的m次方
n >> m -> 计算 n / (2^m), 即除以2的m次方
1 << n -> 2^n
a ^= b
b ^= a
a ^= b
通过 a & (-a) 快速获取a的最后为 1 位置的整数。
00 00 01 01 -> 5
&
11 11 10 11 -> -5
---
00 00 00 01 -> 1
00 00 11 10 -> 14
&
11 11 00 10 -> -14
---
00 00 00 10 -> 2
6.8 其他
集合之间的操作:a | (1 << i) -> 把i插入到集合中
a & ~(1<< i)-> 把i从集合中删除
a & (1<< i) -> 判断i是否属于该集合 (零不属于, 非零属于)
Python中bin一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号,巨坑。
Python中的整型是补码形式存储的。
Python中整型是不限制长度的不会超范围溢出。
所以为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff进行按位与操作,再交给bin()进行输出,得到的才是负数的补码表示。
print(bin(3)) # 0b11
print(bin(-3)) # -0b11
print(bin(-3 & 0xffffffff))
# 0b11111111111111111111111111111101
print(bin(0xfffffffd))
# 0b11111111111111111111111111111101
print(0xfffffffd) # 4294967293
7.练习题
leetcode 习题 136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
尝试使用位运算解决此题。
"""
Input file
example1: [2,2,1]
example2: [4,1,2,1,2]
Output file
result1: 1
result2: 4
"""
class Solution:
def singleNumber(self, nums: List[int]) -> int:
# your code here
x = 0
for num in nums:
x = x ^ num
return x