Python学习笔记
简介
Python由荷兰数学和计算机科学研究学会的Guido van Rossum 于1990 年代初设计,作为一门叫做ABC语言的替代品。
Python提供了高效的高级数据结构,还能简单有效地面向对象编程。
Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。
Python 也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。
变量、运算符和数据类型
1.注释
- 在python中,#表示注释,它可以作用于一整行
#这是一行注释(注释的内容是无法被运行的,一般用于解释和说明代码内容和作用)
print("Hello world")
#Hello world
- 还有一种’’’ ‘’’ 或者 “”" “”" 表示的是区间注释,在两个符号之间的所有内容将会被注释,不会被运行。
【例子】多行注释
'''
这是多行注释,用了三个单引号
第二行也是会被注释掉的
'''
print("Hello china")
# Hello china(单行注释)
"""
同样的,三个双引号也可以进行多行注释。
你看,这两行都注释掉了
"""
print("hello china")
# hello china
注:注释一般用于解释代码,使得别人在看你的代码的时候容易看懂,其次在你注释后,你回来看自己代码的时候也能很快明白当时是怎么敲出来的(特别是你敲了存了很多代码后)
2.运算符
- 算数运算符
操作符 | 名称 | 示例 |
---|---|---|
+ | 加 | 1+1 |
- | 减 | 2-1 |
* | 乘 | 3*4 |
/ | 除 | 4/2 |
// | 整除 | 3//4 |
% | 求余 | 3%4 |
** | 幂 | 3**4 |
【例子】
print(1+1) #2
print(2-1) #1
print(3*4) #12
print(4/2) #2
print(3//4) #0
print(3%4) #3
print(3**4) #81
注:这类运算符中,要注意的是//
和**
,因为这两种在C和Java中是没有的,因为python的数据结构是动态变换的,不像C和Java可以用int
固定类型。(如果没有了解过C和Java的可以跳过这句)
- 比较运算符
操作符 | 名称 | 示例 |
---|---|---|
> | 大于 | 2>1 |
>= | 大于等于 | 2>=4 |
< | 小于 | 2<1 |
<= | 小于等于 | 3<=4 |
== | 等于 | 5==3 |
!= | 不等于 | 5!=3 |
【例子】
print(2>1) #true
print(2>=4) #false
print(2<1) #false
print(3<=4) #true
print(5==3) #false
print(5!=3) #true
- 位运算符
操作符 | 名称 | 示例 |
---|---|---|
~ | 按位取反 | -4 |
& | 按位与 | 4&5 |
| | 按位或 | 4|5 |
^ | 按位异或 | 4^5 |
<< | 左移 | 4<<2,表示整数4按位左移2位 |
>> | 有移 | 4>>2,表示整数4按位右移2位 |
【例子】按位非操作
~ 1 = 0
~ 0 = 1
【例子】按位与操作
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
【例子】按位或操作
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
【例子】按位异或操作
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
【例子】按位左移操作 <<
#00 00 10 11 -> 11
11<<3
#01 01 10 00 -> 88
【例子】按位右移操作 >>
#00 00 10 11 -> 11
11 >> 2
#00 00 00 10 ->2
注:位运算符在一般敲代码时比较少有用到,但是位运算在数据处理上有时要比加减乘除
方便不少,后面会有例子和用法的介绍!!
- 三元运算符
举个例子
x,y = 4,5 #python里时可以用这种语法同时给两个变量赋值!
if x < y :
small = x
else:
small = y
print(small) #4
注:这是传统的判断赋值操作,但是在python有一种特别好用的方式来赋值,三元操作符。(如果If语法不太理解的话我会在后面说明)
【例子】
x , y = 4, 5
small = x if x < y else y
print(small) #4
- 其他运算符(特有)
操作符 | 名称 | 示例 |
---|---|---|
is | 是 | ‘hello’ is ‘hello’ |
not is | 不是 | 3 not is 5 |
in | 存在 | 5 in [1,2,3,4,5] |
not in | 不存在 | 2 not in [1,2,3,4,5] |
【例子】
letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
if 'A' in letters:
print('A' + ' exists')
if 'h' not in letters:
print('h' + ' not exists')
# A exists
# h not exists
【例子】比较的两个变量均指向不可变类型
a = "hello"
b = "hello"
print(a is b, a == b)
# True True
【例子】比较的两个变量均指向可变类型
a = ["hello"]
b = ["hello"]
print(a is b, a == b)
# False True
注意:
- is, is not 对比的是两个变量的内存地址
- ==, != 对比的是两个变量的值
即:
- 假如比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的。
- 假如对比的两个变量,指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。
3.变量和赋值
-
变量名通常由字母,数字,下划线组成;
-
数字不能作为变量名开头;
-
不能以python中的关键字命名;
-
变量名要有意义;(特别是一些变量多的程序显得很重要)
-
不要用汉字和拼音去命名;(一般会使用英语单词)
-
变量名要区分大小写;
-
推荐使用驼峰型(GuessAge或guessAge)和下划线(guess_age)来命名;
-
常量通常使用大写来定义.
【例子】
teacher = "霜鱼的程序世界"
print(teacher) #输出就是teacher变量里的值:霜鱼的程序世界
【例子】
first = 2
second = 3
third = first + second
print(third) #5
#数据类型是数字的两个变量可以进行数学运算
【例子】
myTeacher = "霜鱼的程序世界"
yourTeacher = "小鱼的游戏世界"
ourTeacher = myTeacher + ',' + yourTeacher
print(ourTeacher) #霜鱼的程序世界,小鱼的游戏世界
#同是str,做加法等于把两个字符串组合在一起
4.数据类型与转换
类型 | 名称 | 示例 |
---|---|---|
int | 整形<class ‘int’> | -876,10 |
float | 浮点型<class ‘float’> | 3.149,11.11 |
bool | 布尔型<class ‘bool’> | True,False |
整型
【例子】可以通过print()
看出a的值,以及类(class)是int
a = 1031
print(a,type(a))
#1031 <class 'int'>
注:python里可以用type()
函数来输出括号内变量的数据类型哦!
Python里面万物皆对象(object),和Java差不多,都是面向对象编程的语言,整型也不例外,它也是一个对象,只要是对象,就会有对应的属性和方法
【例子】
b = dir(int)
print(b)
# ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__',
# '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__',
# '__float__', '__floor__', '__floordiv__', '__format__', '__ge__',
# '__getattribute__', '__getnewargs__', '__gt__', '__hash__',
# '__index__', '__init__', '__init_subclass__', '__int__', '__invert__',
# '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',
# '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__',
# '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',
# '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',
# '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
# '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
# '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
# 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag',
# 'numerator', 'real', 'to_bytes']
注:dir(int)其实就是把int数据类型的属性和方法都存放在b这个变量,然后通过print()
函数来进行输出。目前大概知道有这么个情况就好啦,具体要知道这些属性和方法要怎么使用还得去查一查文档。
【例子】找到一个整数的二进制表示,再返回其长度
a = 1031
print(bin(a)) #0b10000000111
print(a.bit_length()) #11
注:bin()
该函数可以把数值转化为二进制数,然后bit_length()
方法则是返回比特长度。
浮点数
【例子】
print(1,type(1))
# 1 <class 'int'>
print(1.,type(1.))
# 1. <class 'float'>
a = 0.00000023
b = 2.3e-7
print(a) #2.3e-07
print(b) #2.3e-07
注:有时候我们想要保留浮点型的小数点后n位,我们其实可以使用decimal包里面的decimal对象和getcontext()
方法来实现
比如
import decimal
from decimal import Decimal
注:解释一下,import
是一个导入包的关键词,import (包名)就可以导入包了。然后from decimal import Decimal
则是从decimal包里导入Decimal对象,也就是从包里导入某个对象!!
补充:其实如果你想知道decimal里面有什么属性和方法的话可以用上面提到的dir(decimal)
来查看哦!!
【例子】getcontext() 显示了 Decimal 对象的默认精度值是 28 位 (prec=28)。
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
布尔值
布尔(boolean)型变量只有两个值可以取,True和False。还有一个形式,你可以把布尔型变量用在数字运算中,可以用1代表True,用0代表False。(需要注意的是True!=true,False!=false哦!)
【例子】
print(True + True) #2
print(True + False) #1
print(True + False) #0
除了直接给变量赋值True和False之外呢,还可以用bool(X)
来创建变量,其中里面的X可以是
- 基本类型:整型(int)、浮点型(float)、布尔型(bool)
- 容器类型:字符串(str)、元组(tuple)、列表(list)、字典(dict)和集合(set)
【例子】bool 作用在基本类型变量:X 只要不是整型 0、浮点型 0.0,bool(X) 就是 True,其余就是 False。
print(type(0), bool(0), bool(1))
# <class 'int'> False True
print(type(10.31), bool(0.00), bool(10.31))
# <class 'float'> False True
print(type(True), bool(False), bool(True))
# <class 'bool'> False True
【例子】bool 作用在容器类型变量:X 只要不是空的变量,bool(X) 就是 True,其余就是 False。
print(type(''), bool(''), bool('python'))
# <class 'str'> False True
print(type(()), bool(()), bool((10,)))
# <class 'tuple'> False True
print(type([]), bool([]), bool([1, 2]))
# <class 'list'> False True
print(type({}), bool({}), bool({'a': 1, 'b': 2}))
# <class 'dict'> False True
print(type(set()), bool(set()), bool({1, 2}))
# <class 'set'> False True
注:确定bool(X) 的值是 True 还是 False,就看 X 是不是空,空的话就是 False,不空的话就是 True。
- 对于数值变量,0, 0.0 都可认为是空的。
- 对于容器变量,里面没元素就是空的。
获取类型信息
- 获取类型信息
type(object)
【例子】
print(isinstance(1, int)) # True
print(isinstance(5.2, float)) # True
print(isinstance(True, bool)) # True
print(isinstance('5.2', str)) # True
type()
不会认为子类是一种父类类型,不考虑继承关系isinstance()
会认为子类是一种父类类型,考虑继承关系
注意:如果要判断两个类型是否相同推荐使用isinstance()
类型转换
- 转换为整型
int(x,base=10)
- 转换为字符串
str(object=' ')
- 转换为浮点型
float(x)
【例子】
print(int('520')) # 520
print(int(520.52)) # 520
print(float('520.52')) # 520.52
print(float(520)) # 520.0
print(str(10 + 10)) # 20
print(str(10.1 + 5.2)) # 15.3
5.print()函数
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
- 将对象以字符串表示的方式格式化输出到流文件对象file里。其中所有非关键字参数都按
str()
方式进行转换为字符串输出; - 关键字参数sep是实现分隔符,比如多个参数输出的时候想要输出中间的分隔字符;
- 关键字参数end是输出结束时的字符,默认时换行符\n;
- 关键字参数file时定义流输出的文件,可以是标准的系统输出sys.stdout,也可以重定义为别的文件;
- 关键字参数flush是立即把内容输出到流文件,不做缓存。
【例子】没有任何参数时,每次的输出都会进行换行。
shoplist = ['apple', 'mango', 'carrot', 'banana']
print("This is printed without 'end'and 'sep'.")
for item in shoplist:
print(item)
# This is printed without 'end'and 'sep'.
# apple
# mango
# carrot
# banana
【例子】每次输出结束都用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
值与'another string'
两个值之间用sep设置的参数&分割。由于end参数没有设置,因此默认是输出解释后换行,即end参数的默认值为\n。
shoplist = ['apple', 'mango', 'carrot', 'banana']
print("This is printed with 'sep='&''.")
for item in shoplist:
print(item, 'another string', sep='&')
# This is printed with 'sep='&''.
# apple&another string
# mango&another string
# carrot&another string
# banana&another string
位运算符
原码、反码和补码
二进制一般有三种不同的表现形式:原码、反码和补码,通常计算机时用补码来表示的。
原码:其实就是二进制表示
二进制表示有两种情况:
无符号和有符号(有符号第一位为符号位)
【例】有符号
00 00 00 01 -> 1
10 00 00 01 -> -1
注:所以如果最前面的数是1,那么就是负数,否则为正数
反码:分正数和负数,正数反码为自己本身,负数反码就是符号位不变,其他取反
【例】
00 00 00 01 -> 1
11 11 11 10 -> -1
补码:正数的补码就是原码,负数的补码就是反码+1
【例】
00 00 00 01 -> 1
11 11 11 11 -> -1
总结:正数的原码、反码和补码都是一样的,负数的反码=原码取反,补码=反码+1=原码取反+1。
符号位:就是最高位,0表示正数,1表示负数。同时注意位运算中,符号位也参与运算哦!!
按位非操作
首先来举个例子吧
~ 1 = 0
~ 0 = 1
欸嘿!~
把数字补码中的0和1全部取反(0变成1,1变成0),有符号的话符号位也会被取反!!!
【例】
00 00 01 01 -> 5
#取反后
11 11 10 10 -> -6
11 11 10 11 -> -5
#取反后
00 00 01 00 -> 4
注:你会发现,其实取反的数都不相同,差距都是1,5取反不等于-5,-5取反也不等于5,联想一下刚刚补码的概念。你就能知道为什么补码要+1了。(因为从这个例子你可以看出,负数+1后就等于正数取负值!!)
按位与操作
还是先给个例子直观感受一下
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
只有两个对应位都是1的时候才为1
【例】
00 00 01 01 -> 5
#上下两个数进行位与操作
00 00 01 10 -> 6
#答案是
00 00 01 00 -> 4
注:你可以把1当作true,0当作false。结合一下“与”的意思,true与false = false,其实就是当两边都同时为true的时候才是true,只要有一方是false也就是0的时候就不行,就是false。
按位或操作
再来看看位或的操作吧!
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
只要两个对应位中有一个是1就为1
【例】
00 00 01 01 -> 5
#位或运算
00 00 01 10 -> 6
#答案
00 00 01 11 -> 7
注:可以联想一下“或”,只要有一个是1(也就是true),那就是true了!所以这些逻辑运算还是很容易理解的。
按位异或操作
举个例子
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
注:只有两个对应位不同时才为1哦!!
【例】
00 00 01 01 -> 5
#按位异或操作
00 00 01 10 -> 6
#答案
00 00 00 11 -> 3
注:异或操作是满足交换律和结合律的!!
【例】
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
按位左移操作
00 00 10 11 -> 11
11 << 3
---
01 01 10 11 -> 88
注:num<<i
将num
的二进制表示向左移动i
位所得的值
按位右移操作
00 00 10 11 -> 11
11 >> 2
---
00 00 00 10 -> 2
注:num>>i
将num
的二进制表示向右移动i
位所得的值!!
利用位运算实现快速计算!!
这是个比较实用的技巧!
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
注:以后可以用<<
和>>
快速计算2的倍数问题。(原理参考二进制!!)
a ^= b
b ^= a
a ^= b
注:可以用^
来快速交换两个整数
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
注:可以通过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 是否属于该集合(零不属于,非零属于)
集合之间的操作:
a 补 -> ~a
a 交 b -> a & b
a 并 b -> a | b
a 差 b -> a & (~b)
注:整数在内存中是以补码的形式存在的,输出自然也是按照补码输出。
有个小知识点:
- Python中
bin
一个负数(十进制表示),输出的是它的原码的二进制表示加上个负号,巨坑。 - Python中的整型是补码形式存储的。
- Python中整型是不限制长度的不会超范围溢出。
【例】
print(bin(3)) # 0b11
print(bin(-3)) # -0b11
print(bin(-3 & 0xffffffff))
# 0b11111111111111111111111111111101
print(bin(0xfffffffd))
# 0b11111111111111111111111111111101
print(0xfffffffd) # 4294967293