PY学习笔记
1 注意事项:
回车键:\r\n 而不是单一个 \r 或 \n
大前提:一定要注意代码的缩进量,代码一定要对齐,不然会报错
缩进:tab
反向缩进:shift + tab
注释:
井号键 #
IDLE:批量注释:alt + 3,取消注释:alt + 4
VS Code:Ctrl + /
安装模块:
pip:在命令行里执行 pip install 模块名,即可自动下载模块并安装,下载速度和成功率和网络质量有关
pip show 模块名:查看某个模块的信息
pip list:列出已安装的模块
查看模块的内容:
? dir(modle)
获取函数信息:
? pythonhelp(function)
删除(释放内存):
? del xxx
数学常量:
? pi(圆周率) ,e(自然常数)
2 数据类型:
布尔型:只有True和False这两个值,运算符为and(与),or(或),not(非)
空值:None,None不等于0,None是一个特殊的空值
普通的数值类型:
整形:0xff、123456
长整型:无限大小的整数,最后一位为大写或小写的“L”(建议大写):0122L、-0x19323L、5192436L
浮点型:1.23e9 (1.23*10^9)、0.000012 (1.2e-5)
复数:a+bj或complex(a,b),a和b均为浮点型
字符串:
用单引号或双引号括起来的内容(可表示转义字符)
转义字符也是字符,在字符串中含有转义字符,如’ac\ne’,则该字符串的值就是’ac\ne’,而在print等函数中输出时,才会把’\n’变为换行命令(2020/08/11)
'a bcd_e#f' (a bcd_e#f)
'I\'m \"OK\"' (I'm "OK")
也可以直接用16进制表示:
r'\u4e2d\u6587' (‘中文’)
注意,在引号外面加r表示引号内的字符串默认不转义:
r'abc\td' (abc\td) 和 'abc\td' (abc d) ### 不知道为啥在直接在python3.7.4版本的shell中输入'abc\td'输出是'abc\td'(2020/23/07)
r'\u4e2d\u6587' (‘中文’) 和 '\u4e2d\u6587' ('\\u4e2d\\u6578')
python还支持拼接字符串:
>>> temp1 = 'test'
>>> temp2 = '_exe_'
>>> temp3 = 10
>>> temp4 = temp1 + temp2 + str(temp3)
>>> temp4
'test_exe_10'
另外,还需注意 str 和 bytes 的区别:
>>>str1 = 'abc'
>>>str1.replace('a','A')
'Abc'
>>>str1
'abc'
>>>str2 = str1.replace('a'.'A')
>>>str1
'abc'
>>>str2
'Abc'
3 容器:
**注意:访问容器中的元素一般都是用中括号 [] 而不是小括号 () 或大括号 {} **
列表:
一种有序的集合,可以随时增减元素,长度为元素的个数(即列表中的列表只算一个元素),空列s表的长度为0。同一个列表内可以有不同数据类型的元素,列表也可以是另一个列表的元素,这和C的结构体很相似。基本操作方法如下:
-
创建: list = ['Michael', 'Bob', 'Tracy'] -
访问: list[0]: 列表第1个元素
list[len(list)-1]: 列表最后一个元素
list[-1]: 列表最后一个元素
当索引超出范围时,会报一个IndexError错误
-
添加: 向 列表末尾 添加:list.append(temp)
向 指定位置 添加:list.insert(i,temp)
-
删除: 删除 指定位置 元素:list.pop(i),删除后返回被删除元素的值
删除 最后一个 元素:list.pop()
-
替换: - list[i] = temp
-
切片: ###对元组、字典、set基本也适用,是比较常用的操作 >>> list1 = [1,2,3,4,5,6]
>>> list2 = list1[0:-1]
>>> list2
[1, 2, 3, 4, 5]
>>> list2 = list1[:]
>>> list2
[1, 2, 3, 4, 5, 6]
>>> list2 = list1[0:-0]
>>> list2
[]
>>> list2 = list1[1:3]
>>> list2
[2, 3]
>>> list2 = list1[0:5:2]
>>> list2
[1, 3, 5]
-
列表生成器:用于生成列表,在原列表地基础上生成新的列表,或批量替换列表中的元素,可以让代码更加简洁 格式 1:
[exp for var in iterable]
exp:表达式
var:变量
iterable:可迭代对象
执行过程:
1,先遍历可迭代对象中的元素
2,将此元素赋值给var
3,将var的值作用到exp这个表达式上
4,将表达式的结果生成一个新列表
如:
>>> l1=[1,2,3,4]
>>> l2=[i*i for i in l1]
>>> print(l1)
>>> print(l2) #[1, 2, 3, 4]
\#[1, 4, 9, 16]
格式 2:
2.1 [exp for var in iterable if 判断条件] ###依次替换为iterable中满足 判断条件 的元素
2.2 [exp if 判断条件 else i for i in iterable] ###依次判断,若满足 判断条件(一般也是 exp in iterable1) 则为 exp ,否则替换为另一个iterable中的元素
2.3 [iterable1[var] if var in iterable1 else var for var in iterable2] ###和2.2类似
大致执行过程:
1,遍历得到每一个元素
2,将遍历得到的元素赋值给var
3,将var的值作用到if语句上
4,如果满足条件就将满足条件的值作用到exp表达式上
5,将exp表达式的运算结果追加到新的列表
如:
>>> aaa=['黑色','红色','白色','黑色']
>>> ccc=['黑色','红色']
>>> bbb=['黄色' if i in ccc else i for i in aaa]
结果:
bbb:['黄色', '黄色', '白色', '黄色']
>>> aaa=['黑色','红色','白色','黑色']
>>> ccc={'黑色':'黄色','红色':'白色'}
>>> bbb=[ccc[i] if i in ccc else i for i in aaa]
结果:
bbb:['黄色', '白色', '白色', '黄色']
-
注意: >>> list1 = ['Jay', 'Bob', 'Den']
>>> list2 = [['Michael', list1, 'Tracy']]
元组:
和列表相似,但其元素的值不可改变:
-
创建: 空元组:tuple = ()
含有多个元素的元组:tuple = (1,2,3)
只含一个元素的元组:tuple = (1,)
注意,由于括号()既可以表示元组,又可以表示数学公式中的小括号,为了避免歧义,只有一个元素的元组也要加逗号,
如:(python在显示只有一个元素的元组时也会加逗号和括号)
>>>tuple = (1)
>>>tuple
1
>>>tuple = (1,)
>>>tuple
(1,)
-
元素值“可变”的元组: >>> list = ['Michael', 'Bob', 'Tracy']
>>> tuple = ('a','b',list)
>>> tuple
('a', 'b', 'Michael', 'Bob', 'Tracy')
>>> list[0] = 'Taylor'
>>> tuple
('a', 'b', 'Taylor', 'Bob', 'Tracy')
解释如下:可以借助C的指针理解,tuple的每一个元素都指向固定的位置,指向不可变,但占据这个位置的元素在特殊情况下(该元素为列表)值发生了改变导致了这种情况 -
另一个易错点: >>> temp = 12
>>> tuple = (1,2,temp)
>>> tuple
(1, 2, 12)
>>> temp = 10
>>> tuple
(1, 2, 12)
此时元组tuple的值没有**“改变”**,即也不能完全按照C的指针和静态指针来理解。
字典:
使用“键-值(key-value)”存储,一个key对应一个value,字典内部存放顺序和key的顺序无关
字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的,但键不行
通过key计算出value的内存地址(哈希算法)实现查找的功能,查找速度不会随着字典的增加而变慢(列表则是采用遍历的方法查找,速度会随着列表大小的变化而变化)(但是字典占用内存多,列表占用内存少),如:
>>> dict = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> dict['Michael']
95
>>> dict[95]
KeyError:95
即只能通过key查找value,不能倒过来
-
操作方法:
-
增加新的键-值对/修改已有的键-值对: >>> dict[key] = value
>>> dict['Jay'] = 100
>>> dict['Michael'] = 97
>>> dict['Michael']
97
>>> dict['Jay']
100
-
判断键-值对是否存在:
>>> 'Thomas' in dict
False
>>> 'Michael' in dict
True
>>> dict.get('Thomas')
>>> dict.get('Thomas',-1)
-1
-
删除:
>>> dict = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> dict.pop('Michael')
95
>>> dict
{'Bob': 75, 'Tracy': 85}
set:
和字典类似,也是一组key的集合,但是不储存value。
要创建一个set,需要提供一个list作为输入集合,通过set(list)输入。显示顺序不代表set是有序的(和字典一样),重复元素在set中自动被过滤。
-
操作:
-
创建:set = set(list) >>> s = set([3,1,2,3])
>>> s
{1, 2, 3}
-
添加:set.add(key) ### 注意,重复添加会自动过滤重复的元素 >>> s.add(4)
>>> s
{1, 2, 3, 4}
-
删除:
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
set和字典都不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”,如把列表放入set则会报错:
>>> list1 = [1,2,3]
>>> set = set([1,list1,2]
TypeError: unhashable type: 'list'
4 基本语法:
if else:
if 条件1 :
逻辑体1
elif 条件2:
逻辑体2
···
else :
逻辑体n
也可以直接地
if 变量 :
...
此时若变量值不为零,则执行if的逻辑,若为零则执行else的逻辑
for循环:
for 变量 in 范围:
逻辑体
如:
>>>names = ['Michael','Bob','Tracy']
>>>for name in names:
print(name)
Michael
Bob
Tracy
while循环:
while(条件):
逻辑体
即满足条件的情况下重复执行逻辑体,使用方法同C
break:
用于退出循环,使用方法同C
continue:
用于跳过本次循环,使用方法同C
pass:
占位符
-
定义函数: def fun_name(parameter1,parameter2...,parameter_n1 = base1,parameter_n2 = base2...):
逻辑体1
return result1
逻辑体2
return result2
···
逻辑体n
return result_n1,result_n2,...
return xxx
-
返回值:
? 若无return语句,则返回值为None,return None也可以简写为return
? 可有多个返回值,使用时返回值按顺序给变量赋值(实际上是返回一个元组,元组的值依次为result_n1,result_n2…),如:
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
- 位置参数:
? 略(就是最普通的参数)
- 默认参数:
***必选参数***在前,***默认参数***在后,否则Python的解释器会报错
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数,如:
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
另外注意,***默认参数必须指向不变对象!!!***否则可能出现一些意想不到的错误,如:
def add_end(L=[]):
L.append('END')
return L
在上面的例子中,默认参数是[],但是函数似乎每次都“记住了**“上次添加了’END’后的list”**,原因解释如下:
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
- 可变参数:
传入参数的数量是可变的,允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此调用该函数时,可以传入任意个参数,如:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
>>> 14
也可以前面加一个*号,把list或tuple的元素变成可变参数传进去:
>>> nums = [1, 2, 3]
>>> calc(*nums)
>>> 14
*nums表示把nums这个list的所有元素作为可变参数传进去。
- 关键字参数:
允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
关键参数可以扩展函数的功能。首先可以保证接收到必选参数,同时在被调用时接收到另外的参数,如:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
>>> name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
简化的写法:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
>>> name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
**extra表示把extra这个字典所有key-value传入到函数的**kw参数,kw将获得一个dict
kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
- 命名关键字参数:
用于限制关键字参数的名字。和关键字参数**kw不同,命名关键字参数*需要一个特殊分隔符*,后面的参数被视为命名关键字参数,如:
### 只接受city和job作为关键字参数:
def person(name, age, *, city, job):
print(name, age, city, job)
### >>> person('Jack', 24, city='Beijing', job='Engineer')
### >>> Jack 24 Beijing Enginee
若函数定义中已有一个可变参数,后面跟着的命名关键字参数就不需要特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
>>> person('Jack', 24, 'Beijing', 'Engineer')
>>> TypeError: person() takes 2 positional arguments but 4 were given
原因:由于调用时缺少参数名city和job,Python解释器把这4个参数均视为位置参数,但person()函数仅接受2个位置参数。
命名关键字参数可以有缺省值,从而简化调用:
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
- 调用模块:
import modle
import modle as xxx
from modle import xxx
5 常用函数:
-
print
>>>print('hellow')
hellow
>>>print("hellow")
hellow
>>>print('''hellow
\tworld''')
hellow
world
>>>print(r'''hellow,\n
world''')
hellow,\nworld
>>> print('a = %d\tb = %d%%'%(a,b))
a = 10 b = 20%
>>> print('a = %.1f\tb = %03d'%(a,b))
a = 10.0 b = 020
>>> print('Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125))
Hello, 小明, 成绩提升了 17.1%
-
input():
>>> data = input('data = ')
data = _
>>> data
'10'
>>> data = int(data)
10
-
类型转换函数: 用于将其他类型变量转为指定类型变量的函数,如上面提到的int(),其他的自行baidu:
int(x [,base ]) 将x转换为一个整数
long(x [,base ]) 将x转换为一个长整数
float(x ) 将x转换到一个浮点数
complex(real [,imag ]) 创建一个复数
str(x ) 将对象 x 转换为字符串
repr(x ) 将对象 x 转换为表达式字符串
eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s ) 将序列 s 转换为一个元组
list(s ) 将序列 s 转换为一个列表
chr(x ) 将一个整数转换为一个字符
unichr(x ) 将一个整数转换为Unicode字符
ord(x ) 将一个字符转换为它的整数值
hex(x ) 将一个整数转换为一个十六进制字符串
oct(x ) 将一个整数转换为一个八进制字符串
int(object,base=10)
object:一个数字或整数字符串
base:object对应的进制,省略时默认为10
返回值:object对应的10进制数
>>> int()
0
>>>temp = '0xac'
>>>int(temp,16)
172
>>> temp = '23.1314'
>>> print(int(float(temp)))
23
-
range(temp): 生成 0~temp-1的 整数序列,常用于for循环里产生一个变量范围
-
list(temp):
>>> list(range(5))
[0,1,2,3,4]
-
ord()和chr():
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
‘B’
>>> chr(25991)
‘文’
-
encode() 和 decode():
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
-
len():
>>>len('中文'.encode('utf-8'))
6
>>>len(b'abd')
3
>>>len(b'\xe4\xb8\xad\xe6\x96\x87')
6
6 值得一提的操作:
-
列表合成字典:
-
构建字典的 2 个列表长度相同 >>> a = [1,2,3,]
>>> b = ['ab','ac','ad']
>>> dict(zip(a,b))
{1: 'ab', 2: 'ac', 3: 'ad'}
-
构建字典的 2 个列表长度不同(key比value多) >>> a = [1,2,3,4]
>>> c = ['aa','ss']
>>> dict(zip(a,c))
{1: 'aa', 2: 'ss'}
-
构建字典的 2 个列表长度不同(key比value少) >>> a = [1,2,3,4]
>>> d = ['fa','fb','fc','fd','fe']
>>> dict(zip(a,d))
{1: 'fa', 2: 'fb', 3: 'fc', 4: 'fd'}
-
字典键值对反转: >>> dict1 = {"zhangsan":'12',"lisi":'13',"wangwu":'15'}
>>> dict2 = {}
>>> for key,val in dict1.items():
dict2[val]=key
-
以指定概率选取元素:
import random
def random_pick(some_list, probabilities):
x = random.uniform(0,1)
cumulative_probability = 0.0
for item, item_probability in zip(some_list, probabilities):
cumulative_probability += item_probability
if x < cumulative_probability:
break
return item
-
删除多个连续空格只保留一个: >>>str1="ww dd ddd"
>>>str2=' '.join(str1.split())
原理:先将字符串通过split函数变为字符数组,再用字符串的隐形转换的特性将数组转换成字符串
|