python学习备忘录,主要内容出自廖雪峰的python基础教程,排版略有些杂乱,继续努力,明天会更好
1.list与tuple的区别
-
都是有序集合
-
list可变,tuple不可变
-
tuple内的list可变
-
list用[],tuple用()
2.条件判断
- input()返回的是字符串,想要做数值比较需要转化数据类型
- if : elif: else
3.循环
-
for name in names:其中name任取,names为属性名称,下面是从1加到100的方法
sum = 0 for x in range(101): sum = sum + x print(sum)
-
while满足条件就不停循环,不满足条件退出循环,计算一百以内奇数之和代码如下
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
-
break作用是提前结束循环
n = 1 while n <= 100: if n > 10: # 当n = 11时,条件满足,执行break语句 break # break语句会结束当前循环 print(n) n = n + 1 print('END')
-
continue作用是跳过某些循环
n = 0 while n < 10: n = n + 1 if n % 2 == 0: # 如果n是偶数,执行continue语句 continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行 print(n)
-
遇到程序死循环Ctrl+C退出程序
4.dict与set比较
-
dict特点
-
查找和插入速度极快,不会随着key的增加而变慢,通过Key查找value的方法为Hash
-
需要占用大量内存,内存浪费多
-
key不可变,整数,字符串都是不可变的可以使用,list可变不能作为key
-
空间换时间
-
无序键值对
-
dict使用{}
-
-
set特点
-
查找和插入的时间随着元素的增加而增加
-
占用空间小,浪费内存很少
-
时间换空间
-
set可以看成数学意义上的无序和无重复元素的集合
-
无序键值对
-
不可放入可变对象
-
set使用{}
注释:str是不可变对象,list是可变对象
-
5.函数的参数
-
默认参数可以简化函数的调用。设置默认参数时,有几点要注意:
-
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
-
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
-
最大的好处是能降低调用函数的难度。
-
默认参数必须指向不变对象
def add_end(L=None): if L is None: L = [] L.append('END') return L
-
-
定义可变参数仅在参数前面加上*即可,调用该函数时可以传入任意个参数,包括0个参数
- 如果已经有一个list或者tuple,要调用一个可变参数怎么办?
*nums
表示把nums
这个list的所有元素作为可变参数传进去
- 如果已经有一个list或者tuple,要调用一个可变参数怎么办?
-
关键字参数kw,可以扩展函数的功能,
-
比如,在
person
函数里,我们保证能接收到name
和age
这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。 -
person('Jack', 24, **extra) extra为字典,对于extra是不影响的,只是拷贝一份
-
-
命名关键字参数
-
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收
city
和job
作为关键字参数。这种方式定义的函数如下:def person(name, age, *, city, job): print(name, age, city, job)
和关键字参数
**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
-
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
顺序:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
6.递归
递归的过程就是不断调用自身的过程,先进后出的思想,递归要用到栈,而栈不像链表,栈会有溢出,解决栈溢出的方法:
- 用栈把递归转换成非递归 不用系统栈,使用自己创建的栈
- 使用static对象替代nonstatic局部对象
- 增大堆栈大小值
7.列表生成式[]
[x * x for x in range(1, 11) if x % 2 == 0]
[m + n for m in 'ABC' for n in 'XYZ']
for
循环其实可以同时使用两个甚至多个变量,比如dict
的items()
可以同时迭代key和value:
>>> d = {
'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k, v in d.items():
... print(k, '=', v)
...
y = B
x = A
z = C
8.生成器generator()
9.map/reduce
map()将运算规则抽象,接收两个参数,一个是函数一个是Iterable
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
reduce()把结果继续和序列的下一个元素做累积计算
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
把list转换为int
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
把str
转换为int
的函数:
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> def char2num(s):
... digits = {
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
... return digits[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579
10.迭代器
直接作用于for循环的数据类型有:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function
可以直接 作用于for循环的对象统称为可迭代对象:iterable
可用isinstance(,Iterable)判断是否为iterable对象
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator表示惰性计算的序列
。
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
11.lambda
- 一个语法
lambda argument_list: expression
argument_list是参数列表。
expression是表达式,表达式中出现的参数需要在argument_list中定义,并且表达式只能是单行。
-
三个特性
lambda函数是匿名的
lambda函数有输入和输出
lambda函数一般功能简单
-
四个用法
- 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数
例如:add = lambda x,y:x+y add变为具有加法功能的函数
-
将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换
例如,为了把标准库time中的函数sleep的功能屏蔽(Mock),我们可以在程序初始化时调用:time.sleep=lambda x:None。这样,在后续代码中调用time库的sleep函数将不会执行原有的功能。例如,执行time.sleep(3)时,程序不会休眠3秒钟,而是什么都不做。
-
将lambda函数作为其他函数的返回值,返回给调用者
函数的返回值也可以是函数。例如return lambda x, y: x+y返回一个加法函数,内部函数能够访问外部函数的局部变量,这个特性是闭包(Closure)编程的基础
-
将lambda函数作为参数传递给其他函数。
filter(),sorted(),map(),reduce()
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
12.定制类
slots:限制实例的使用
slots=(‘name’,‘age’)
@property把方法当做属性使用,不定义setter方法就是一个只读属性
@属性.setter设置set方法
13.多重继承
class Bat(Mammal,Flyable):
psss
通过多重继承,一个子类就可以同时获得多个父类的所有功能
14.MixIn
MixIn的目的就是给一个类添加多个功能
15.枚举类Enum
from enum import Enum
Month = ('Month',('Jan','Feb','Mar','Apr','May,'Jun'))
引用枚举类
for name, member in Month.__members__.items():
print(name, '=>', member,',', member.value)
如果需要更加精确的控制枚举类型,可以从Enum派生出自定义类
from enum import Enum, unique
@unique
class Weekday(Enum):
Sun = 0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
@unique装饰器可以帮助我们检查保证没有重复值
动态语言和静态语言最大的区别在于,就是函数和类的定义不是在编译时定义的而是在运行时动态创建的
###16.type()使用
1.可以查看一个类型或者变量的类型
2.动态创建class
>>> def fn(self, name='world'): # 先定义函数
... print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
-
class的名称;
-
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
-
class的方法名称与函数绑定,这里我们把函数
fn
绑定到方法名hello
上。
16.with
Python引入了with
语句来自动帮我们调用close()
方法:
with open('/path/to/file', 'r') as f:
print(f.read())
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
如果文件很小,read()
一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()
最方便:
for line in f.readlines():
print(line.strip()) # 把末尾的'\n'删掉
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesI
17.序列化
我们把变量从内存中变成可存储或传输的过程称之为序列化叫picking
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
pickle.dumps()方法把任意对象序列化成一个
bytes
>>> import pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d)
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
pickle.dump()
直接把对象序列化后写入一个file-like Object:
>>> f = open('dump.txt', 'wb')
>>> pickle.dump(d, f)
>>> f.close()
我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes
,然后用pickle.loads()
方法反序列化出对象,也可以直接用pickle.load()
方法从一个file-like Object
中直接反序列化出对象。我们打开另一个
18.进程与线程
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。
多进程和多线程的程序涉及到同步、数据共享的问题,编写起来更复杂。
-
多进程
一个
ThreadLocal
变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal
解决了参数在一个线程中各个函数之间互相传递的问题
19.正则表达式
判断一个字符串是否是合法的Email地址,
1.创建一个匹配Email的正则表达式
2.用该正则表达式去匹配用户的输入是否合法
20.虚拟环境
创建虚拟环境
virtualenv -p “环境” 虚拟环境名称
打开虚拟环境
.\虚拟环境名称\scripts\activate
关闭虚拟环境
.\虚拟环境名称\scripts\deactivate
20.git使用
git config --global user.name “”
git config --global user.email “”
git config --global --list
git init
添加所有
git add.
查看状态
git status
提交到本地仓库
git commit -m “注释”
git log查看日志
git diff查看文件改变细节
恢复版本
git reset --hard HEAD^恢复到上一个版本
git reset --hard HEAD^^恢复到上上个版本
git reset --hard 版本号
git reflog 找到之前的版本号
出现end可以使用q 退出
添加远程仓库
git remote add origin “克隆地址”
第一次,用远程来初始化本地(两个仓库合并)
git pull origin master --allow-unrelated-histories
提交到码云
git push origin master 输入用户名和密码后完成
如何保存用户名和密码
git config --global credential.helper store
21.判断
除了False和0其他的都是True