一、学习知识点概要
- python如何进行注释
- 运算符以及运算符的优先级
- 变量,数据类型以及简单类型的数据转换
- print()函数的输出规则
- 位运算及运用
- 条件语句、循环语句
- python的异常总结,如何捕获异常,抛出异常
二、学习内容
1. 运算符与数据类型
运算符
算术运算符
+
,-
,*
,/
,//
(整除),%
(取余),**
(幂)
比较运算符
>
,>=
,<
,<=
,==
,!=
逻辑运算符
and
,or
,not
位运算符
~
(按位取反),&
(按位与),|
(按位或),^
(按位异或),<<
(左移),>>
(右移)
三元运算符
x, y = 4, 5
small = x if x < y else y
print(small) # 4
其他运算符
in
,not in
,is
,not is
is
,not is
比较的是地址,==
,!=
比较的是值
a = "hello"
b = "hello"
c = ["hello"]
d = ["hello"]
print(a is b, a == b) # True True
print(a is not b, a != b) # False False
print(c is d, c == d) # False True
print(c is not d, c != d) # True False
运算符的优先级
运算符 | 描述 |
---|---|
** | 指数(最高优先级) |
~± | 按位翻转,一元加号和减号 |
* / % // | 乘,除,取模和取整除) |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位‘AND’ |
^| | 位运算符 |
<=<>>= | 比较运算符 |
<>==!= | 等于运算符 |
=%=/=//=-=+=*=**= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
数据类型
简单数据类型
-
整型<class ‘int’>
-
浮点型<class ‘float’>
若要保留浮点型的小数点后
n
位,可以用decimal
包里的Decimal
对象和getcontext()
方法来实现。import decimal from decimal import Decimal decimal.getcontext().prec = 4 #默认是28位 c = Decimal(1) / Decimal(3) print(c)
-
布尔型<class ‘bool’>
只能取两个值,
True
和False
。可以通过bool(X)
来创建变量,其中X
可以是- 基本类型:整型、浮点型、布尔型
X
只要不是整型0
、浮点型0.0
,布尔型false
,bool(X)
就是True
,其余就是False
。
- 容器类型:字符串、元组、列表、字典和集合
X
只要不是空的变量,bool(X)
就是True
,其余就是False
。
- 基本类型:整型、浮点型、布尔型
容器数据类型
- 列表<class ‘list’>
- 元组<class ‘tuple’>
- 字典<class ‘dict’>
- 集合<class ‘set’>
- 字符串<class ‘str’>
获取类型信息
type(object)
不会认为子类是一种父类类型,不考虑继承关系。isinstance(object,object)
会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()
。
print函数
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
- 将对象以字符串表示的方式格式化输出到流文件对象file里。其中所有非关键字参数都按
str()
方式进行转换为字符串输出; - 关键字参数
sep
是实现分隔符,比如多个参数输出时想要输出中间的分隔字符; - 关键字参数
end
是输出结束时的字符,默认是换行符\n
; - 关键字参数
file
是定义流输出的文件,可以是标准的系统输出sys.stdout
,也可以重定义为别的文件; - 关键字参数
flush
是立即把内容输出到流文件,不作缓存。
2. 位运算
前提知识
计算机内部使用补码来表示。 最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。
按位运算
按位非操作
~4=-5
解析:
- 将4转为补码,正数原码反码补码都一样,4的补码为4—0100,最高位0为符号位。
- 按位进行非运算,0100→1011
- 1011取补码→1101→-5
公式:~x = -(x+1),除了1和0,~1=0,~0=1
异或操作
相同为0,不同为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
A^B^A: = A^A^B = B = 00 00 01 11
利用位运算实现快速计算
通过 <<
,>>
快速计算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 位置的整数。
利用位运算实现整数集合
一个数的二进制表示可以看作是一个集合(0 表示不在集合中,1 表示在集合中)。
比如集合 {1, 3, 4, 8}
,可以表示成 01 00 01 10 10
而对应的位运算也就可以看作是对集合进行的操作。
元素与集合的操作:
a | (1<<i) → 把 i 插入到集合中
a & ~(1<<i) → 把 i 从集合中删除
a & (1<<i) → 判断 i 是否属于该集合(零不属于,非零属于)
3. 条件语句
assert 关键词
assert
这个关键词我们称之为“断言”,当这个关键词后边的条件为 False 时,程序自动崩溃并抛出AssertionError
的异常。
assert 3 > 7
# AssertionError
4. 循环语句
while - else 循环
while 布尔表达式:
代码块
else:
代码块
当while
循环正常执行完的情况下,执行else
输出,如果while
循环中执行了跳出循环的语句,比如 break
,将不执行else
代码块的内容。
for - else 循环
for 迭代变量 in 可迭代对象:
代码块
else:
代码块
当for
循环正常执行完的情况下,执行else
输出,如果for
循环中执行了跳出循环的语句,比如 break
,将不执行else
代码块的内容,与while - else
语句一样。
range() 函数
range([start,] stop[, step=1])
step=1
表示第三个参数的默认值是1。range
的作用是生成一个从start
参数的值开始到stop
参数的值结束的数字序列,该序列包含start
的值但不包含stop
的值。
enumerate()函数
enumerate(sequence, [start=0])
- sequence:一个序列、迭代器或其他支持迭代对象。
- start:下标起始位置。
- 返回 enumerate(枚举) 对象
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
lst = list(enumerate(seasons))
print(lst)
# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
pass 语句
pass
语句的意思是"不做任何事",如果你在需要有语句的地方不写任何语句,那么解释器会提示出错,而 pass
语句就是用来解决这些问题的。
def a_func():
pass
推导式
列表推导式
[ expr for value in collection [if condition] ]
x = [i ** 2 for i in range(1, 10)]
print(x)
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]
print(x)
# [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]
a = [(i, j) for i in range(0, 3) for j in range(0, 3)]
print(a)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
元组推导式
( expr for value in collection [if condition] )
a = (x for x in range(10))
print(a)
# <generator object <genexpr> at 0x0000025BE511CC48>
print(tuple(a))
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
字典推导式
{ key_expr: value_expr for value in collection [if condition] }
b = {i: i % 2 == 0 for i in range(10) if i % 3 == 0}
print(b)
# {0: True, 3: False, 6: True, 9: False}
集合推导式
{ expr for value in collection [if condition] }
c = {i for i in [1, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1]}
print(c)
# {1, 2, 3, 4, 5, 6}
其它
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.
e = (i for i in range(10))
print(e)
# <generator object <genexpr> at 0x0000007A0B8D01B0>
print(next(e)) # 0
print(next(e)) # 1
for each in e:
print(each, end=' ')
# 2 3 4 5 6 7 8 9
5. 异常处理
Python 常见异常总结
- BaseException:所有异常的 基类
- Exception:常规异常的 基类
- StandardError:所有的内建标准异常的基类
- ArithmeticError:所有数值计算异常的基类
- FloatingPointError:浮点计算异常
- OverflowError:数值运算超出最大限制
- ZeroDivisionError:除数为零
- AssertionError:断言语句(assert)失败
- AttributeError:尝试访问未知的对象属性
- IOError:输入/输出操作失败
- OSError:操作系统产生的异常(例如打开一个不存在的文件)
- ImportError:导入模块失败的时候
- IndexError:索引超出序列的范围
- KeyError:字典中查找一个不存在的关键字
- MemoryError:内存溢出(可通过删除对象释放内存)
- NameError:尝试访问一个不存在的变量
- SyntaxError:语法错误导致的异常
- RuntimeError:一般的运行时异常
- TypeError:不同类型间的无效操作
- ValueError:传入无效的参数
try - except 语句
try:
检测范围
except Exception[as reason]:
出现异常后的处理代码
- 执行
try
子句(在try
和except
之间的语句) - 如果没有异常发生,忽略
except
子句,try
子句执行后结束。 - 如果在执行
try
子句的过程中发生了异常,那么try
子句余下的部分将被忽略。如果异常的类型和except
之后的名称相符,那么对应的except
子句将被执行。最后执行try - except
语句之后的代码。 - 如果一个异常没有与任何的
except
匹配,那么这个异常将会传递给上层的try
中。
try:
f = open('test.txt')
print(f.read())
f.close()
except OSError as error:
print('打开文件出错\n原因是:' + str(error))
# 打开文件出错
# 原因是:[Errno 2] No such file or directory: 'test.txt'
一个try
语句可能包含多个except
子句,分别来处理不同的特定的异常。最多只有一个分支会被执行
try:
int("abc")
s = 1 + '1'
f = open('test.txt')
print(f.read())
f.close()
except OSError as error:
print('打开文件出错\n原因是:' + str(error))
except TypeError as error:
print('类型出错\n原因是:' + str(error))
except ValueError as error:
print('数值出错\n原因是:' + str(error))
# 数值出错
# 原因是:invalid literal for int() with base 10: 'abc'
一个 except
子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组。
try:
s = 1 + '1'
int("abc")
f = open('test.txt')
print(f.read())
f.close()
except (OSError, TypeError, ValueError) as error:
print('出错了!\n原因是:' + str(error))
# 出错了!
# 原因是:unsupported operand type(s) for +: 'int' and 'str'
try - except - finally 语句
try: 检测范围
except Exception[as reason]: 出现异常后的处理代码
finally: 无论如何都会被执行的代码
不管try
子句里面有没有发生异常,finally
子句都会执行。
如果一个异常在try
子句里被抛出,而又没有任何的except
把它截住,那么这个异常会在finally
子句执行后被抛出。
def divide(x, y):
try:
result = x / y
print("result is", result)
except ZeroDivisionError:
print("division by zero!")
finally:
print("executing finally clause")
divide(2, 0)
# division by zero!
# executing finally clause
try - except - else 语句
如果在try
子句执行时没有发生异常,Python将执行else
语句后的语句。
try:
检测范围
except Exception[as reason]:
出现异常后的处理代码
else:
如果没有异常执行这块代码
raise语句
Python 使用raise
语句抛出一个指定的异常。
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
# An exception flew by!
三、学习问题与解答
1. 按位非操作~
是如何实现的?
参考了一些技术论讨的解答之后,我也终于弄明白了。
首先要知道计算机内部是使用 补码 来存数字的
~(-5) = 4
解析:
- -5的原码是:1101,最高位为符号位(1代表负数,0代表正数)
- 负数的反码为原码除符号位外各个位数取反,-5取反 → 1010
- 负数的补码为反码+1,-5的补码 → 1010+1 → 1011
- 按位进行非运算(符号位也要进行非运算),~1011→ 0100
- 0100为4,正数,反码补码都一样,所以最终结果为4。
由此可以得出,公式:~x = -(x+1),除了1和0,~1=0,~0=1。
四、学习思考与总结
Task1学习到了很多python的基础知识,但对某些操作比较陌生,需要勤加练习。虽然按位非操作在课程内容上没有很详细的解析,但也给我提供了解决问题的动力。