目录
小前提:元组tuple和列表list都是一种有序列表,二者又有所区别。
主要参考:百家号
- 申明与赋值:元组使用小括号,列表使用方括号,元素之间也是用英文逗号分隔,当元组只有一个元素时,需要在元素的后面加一个英文逗号分隔符,以防止与表达式中的小括号混淆;
- 元组是不可修改类型,不能对元组的元素进行插入和删除运算,只能通过再构造一个新的元组替换旧的元组来实现。
1. 元组tuple
a_tuple=(1,6,7,12) #元组的定义可以用()或什么都不加
b_tuple=3,4,5,7
a_list=[12,2,4,5,9] #列表的定义用[]
for a in b_tuple:
print(a)
for index in range(len(a_list)):
print('index=',index,'number in list=',a_list[index])
结果为
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/3.py
3
4
5
7
index= 0 number in list= 12
index= 1 number in list= 2
index= 2 number in list= 4
index= 3 number in list= 5
index= 4 number in list= 9
2. 列表list
a=[3,6,7,2,10,7]
b=[1,2]
c=[2,4,6]
d=[1,3,4,5,6,7,8]
#添加
a.append(9)
#print(a)
print('a appended is:',a)
b.insert(2,8) #insert函数,第一个参数表示列表的位置,第二个参数表示具体加的数字
print("b inserted is:",b)
#移除
c.remove(2) #表示去掉原列表中首次出现的2
print('c removed is:',c)
#特定打印
print(d[2]) #打印列表中第二位
print(d[-1]) #打印列表中最后一位,用-1表示 -i表示倒数第i位
print(d[0:3]) #打印列表中前三位(即0、1、2位),用:,等价于print(a[:3])
print(d[3:]) #打印列表中第三位及以后
#索引
print(a.index(2)) #第一次出现2的位数,index后面的值是列表中的数值
#查看某个数字出现的次数
print(a.count(7)) #计算列表中出现7的次数
#排序
a.sort() #sort后不加参数,默认从小到大排序
print('small to big is:',a)
a.sort(reverse=True) #sort加参数,从大到小排序
print('big to small is:',a)
结果为
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/3.py
a appended is: [3, 6, 7, 2, 10, 7, 9]
b inserted is: [1, 2, 8]
c removed is: [4, 6]
4
8
[1, 3, 4]
[5, 6, 7, 8]
3
2
small to big is: [2, 3, 6, 7, 7, 9, 10]
big to small is: [10, 9, 7, 7, 6, 3, 2]
3. 多维列表
用到模块 numpy、pandas
a=[1,2,3] #一维list
muti_a=[[1,2,3],[2,5,4],[6,4,5]] #多维list
print(a[1])
print(muti_a[0][2]) #多维下的第0行,第2列
结果为
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
2
3
4. 字典 dictionary
与 list 类似,dictionary功能更多,但是存档形式无需顺序
a_list=[1,2,3] #一维 dictionary
b_dic={'apple':1,'orange':[1,2],'pear':3} #key与内容value对应,内容可以是字典嵌套
c_dic={1:'monday','no':'saturday'} #与上面形式不同,但是仍然是key与内容对应的形式
print(a_list[1])
print(b_dic['apple']) #多维下的第0行,第2列
#删除元素
del b_dic['pear']
print(b_dic)
#增加元素
c_dic['sunday']=3
print(c_dic) #增加后打印出的不一定按顺序
结果为
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
2
1
{'apple': 1, 'orange': [1, 2]}
{1: 'monday', 'no': 'saturday', 'sunday': 3}
5. import 模块
5.1 import+模块,模块可以是 python 自带或者自己安装的,
import time #加载模块的第一种方法
#import time as t #模块简称为t
#from time import time,localtime #加载time中的指定模块
#from time import * #加载time中所有功能,也可以直接调用localtime()
print(time.localtime())
#print(time.time())
#print(localtime()) 第三种,前面就不用加time了
结果
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
time.struct_time(tm_year=2018, tm_mon=3, tm_mday=17, tm_hour=9, tm_min=21, tm_sec=44, tm_wday=5, tm_yday=76, tm_isdst=0)
5.2 import自己创建的模块
自己的模块可以在python默认的外部模块地址下,也可以在和调用它的模块在同一目录下
6. 循环中的 continue、break
a=True
while a:
b=input('type something')
if b=='1':
#a=False
break #终止
#continue #直接跳过后面的,重复上面的
else:
pass #表示什么也不做
print('finish run')
结果
>>>
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
type something2
type something3
type something1
finish run
7. 错误处理try
try:
file=open('abc','r+w')
except Exception as e: #将报错存储在e中
print(e)
print("there is no file name as abc")
response = input('do you want to create a new file as abc?')
if response=='y':
file=open('abc','w')
else:
pass
else: #与try对应
file.write('string:abc') #写入的内容
file.close()
输出结果为
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
[Errno 2] No such file or directory: 'abc'
there is no file name as abc
do you want to create a new file as abc?y
8. zip、map、lambda功能
zip:zip函数接收任意多个序列作为参数,合并后返回一个 tuple 列表,zip(a,a,b)也可以
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> zip(a,b)
<zip object at 0x0000000002E5AEC8> #返回的是一个功能
>>> list(zip(a,b)) #要想可视化,变成list
[(1, 4), (2, 5), (3, 6)]
>>> for i,j in zip(a,b):
print(i/2,j*2)
0.5 8
1.0 10
1.5 12
lambda:定义简单函数,实现简化代码的功能
>>> def fun1(x,y)
SyntaxError: invalid syntax
>>> def fun1(x,y):
return x+y
>>> fun1(3,4)
7
>>> fun2=lambda x,y:x-y #冒号前的x,y为自变量,冒号后x+y为具体运算
>>> fun2(9,3)
6
map:把函数和参数绑定在一起
>>> list(map(fun1,[2,4],[1,6]))
[3, 10]
>>> list(map(fun1,[2,4,7],[1,6])) #参数形式必须一样,否则最后一个数字不识别
[3, 10]
>>> list(map(fun1,[2,4,7],[1,6,4]))
[3, 10, 11]
9. copy & deepcopy 浅复制&深复制
copy也是 python 中的一个模块
>>> import copy
>>> a=[2,4,5]
>>> b=a #第一种:完全copy,在内存中处于同一位置
>>> id(a)
48606984
>>> id(b)
48606984
>>> b[0]=9 #改变b的值,a的值也会相应变化
>>> a
[9, 4, 5]
>>> print(id(a)==id(b))
True
>>> c=copy.copy(a) #第二种:浅copy,只copy最外围的对象本身,
>>> print(id(a)==id(c)) #id不同
False
>>> c[1]=22
>>> a
[9, 4, 5]
>>> c
[9, 22, 5]
>>> a=[1,2,[3,4]] #处于第二层的[3,4]的id不会被copy,所以也没有变化
>>> d=copy.copy(a)
>>> id(a)==id(d)
False
>>> id(a[2])==id(d[2]) #第二层(外围)id一样
True
>>> a[0]=11
>>> d
[1, 2, [3, 4]]
>>> a[2][0]=33
>>> d
[1, 2, [33, 4]]
>>> e=copy.deepcopy(a) #第三种copy,对外围和内部都进行了copy,id不同
>>> e
[11, 2, [33, 4]]
>>> id(e[2])==id(a[2])
False
>>> id(e)==id(a)
False
10. 多线程
参考https://morvanzhou.github.io/tutorials/python-basic/threading/
10.1 添加线程
import threading
def thread_job():
print('this is an added Thread,number is %s'% threading.current_thread()) # % 前不能加,
def main():
added_thread=threading.Thread(target=thread_job) #添加的线程,大写“T”,实现的功能是thread_job
print(threading.active_count()) #获取已激活的线程数
print(threading.enumerate()) #查看所有线程信息
print(threading.current_thread()) #查看现在正在运行的线程
added_thread.start() #运行添加的线程
if __name__=='__main__': # :不能丢
main()
结果
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
2
[<_MainThread(MainThread, started 8320)>, <Thread(SockThread, started daemon 4324)>]
<_MainThread(MainThread, started 8320)>
this is an added Thread,number is <Thread(Thread-1, started 8604)>
>>>
多线程与单线程执行耗时比较:https://www.cnblogs.com/rrxc/p/4103367.html
import threading
from time import sleep
import time
def task1():
print("Task 1 executed")
sleep(1)
def task2():
print("Task 2 executed")
sleep(5)
print("多线程:")
time_start = time.time()
threads = [] #创建一个线程列表,用于存放需要执行的子线程
t1 = threading.Thread(target=task1) #创建第一个子线程,子线程的任务是调用task1函数,注意函数名后不能有()
threads.append(t1) #将这个子线程添加到线程列表中
t2 = threading.Thread(target=task2) #创建第二个子线程
threads.append(t2)
for t in threads: #遍历线程列表
t.setDaemon(True) #将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起
t.start() #启动子线程
time_end = time.time()
total_time = time_end - time_start
print("多线程下耗时:",format(total_time))
print(threading.active_count()) #获取已激活的线程数
print(threading.enumerate()) #查看所有线程信息
print(threading.current_thread()) #查看现在正在运行的线程
#单线程
print("单线程:")
start_time = time.time()
task1()
task2()
end_time = time.time()
totaltime = end_time - start_time
print("单线程下耗时:",format(totaltime))
'''
D:\应用软件\python\python.exe F:/BaiduNetdiskDownload/04-深度学习课程/TensorFlow教程/Tensorflow视频教程/tensorflowTUT源码/RNN.py
多线程:
Task 1 executed
Task 2 executed
多线程下耗时: 0.0009999275207519531
3
[<Thread(Thread-2, started daemon 14720)>, <Thread(Thread-1, started daemon 12460)>, <_MainThread(MainThread, started 15332)>]
<_MainThread(MainThread, started 15332)>
单线程:
Task 1 executed
Task 2 executed
单线程下耗时: 6.0
Process finished with exit code 0
'''
结果显示:多线程耗时远远小于单线程。
10.2 join功能
join:在启动线程后调用 join,可以使输出顺序按我们想要的来。
import threading
import time
def thread_job():
print('T1 start\n')
for i in range(10):
time.sleep(0.1)
print('T1 finish\n')
def main():
added_thread=threading.Thread(target=thread_job,name='T1') #添加的线程,大写“T”,实现的功能是thread_job
added_thread.start() #开始添加的线程
added_thread.join() #若不加join,则不会按我们想要的顺序执行
print('all done\n')
if __name__=='__main__': # :不能丢
main()
加了 join 的运行结果
>>> T1 finish
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
T1 start
T1 finish
all done
不加 join 的运行结果
>>> T1 finish
RESTART: C:/Users/Administrator/AppData/Local/Programs/Python/Python36/4.py
T1 start
all done
>>> T1 finish
10.3 queue功能
线程没有返回值,需要放在队列中
import threading
import time
from queue import Queue #队列的标准模块
def job(l,q):
for i in range(len(l)):
l[i]=l[i]**2
q.put(l)
def multithreading():
q=Queue() #多线程函数中的Queue用来保存返回值
threads=[]
data=[[1,2,3],[3,4,3],[4,5,5],[5,6,7]]
for i in range(4): #定义四个线程
t=threading.Thread(target=job,args=(data[i],q))
t.start()
threads.append(t) #把每个线程append到线程列表中
for thread in threads:
thread.join()
results=[]
for _ in range(4):
results.append(q.get()) #q.get()表示按顺序从q中拿出一个值
print(results)
if __name__=='__main__': # :不能丢
multithreading()
'''
[[1, 4, 9], [9, 16, 9], [16, 25, 25], [25, 36, 49]]
'''
10.4 GIL不一定有效率
python的多线程不是同时进行,是通过线程之间不停的切换实现的,且一次性只能处理一个东西,即GIL,所以不一定达到大量缩短时间的效果。
GIL:http://cenalulu.github.io/python/gil-in-python/
import threading
from queue import Queue
import copy
import time
def job(l, q):
res = sum(l)
q.put(res)
def multithreading(l):
q = Queue()
threads = []
for i in range(4):
t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
t.start()
threads.append(t)
[t.join() for t in threads]
total = 0
for _ in range(4):
total += q.get()
print(total)
def normal(l):
total = sum(l)
print(total)
if __name__ == '__main__':
l = list(range(1000000))
s_t = time.time()
normal(l*4)
print('normal: ',time.time()-s_t)
s_t = time.time()
multithreading(l)
print('multithreading: ', time.time()-s_t)
结果为
RESTART: C:\Users\Administrator\AppData\Local\Programs\Python\Python36\4.py
1999998000000
normal: 0.17600011825561523
1999998000000
multithreading: 0.13700008392333984
按理来说,预计线程下会快3-4倍,但实际上并没有,就是因为 GIL 的原因。
10.5 Lock锁
lock 在不同线程使用同一内存时,能确保线程之间互不影响,使用lock的方法是, 在每个线程执行运算修改共享内存之前,执行lock.acquire()
将共享内存上锁, 确保当前线程执行时,内存不会被其他线程访问,执行运算完毕后,使用lock.release()
将锁打开, 保证其他的线程可以使用该共享内存。
import threading
def job1():
global A,lock
#lock.acquire()
for i in range(10):
A+=1
print('job1',A)
#lock.release()
def job2():
global A,lock
#lock.acquire()
for i in range(10):
A+=10
print('job2',A)
#lock.release()
if __name__=='__main__':
#lock=threading.Lock()
A=0
t1=threading.Thread(target=job1)
t2=threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
结果为(注意:此结果并不一定每次一样,也可能是完好的结果,结果并不固定)
job1job2 11
job2 21
job2 31
job2 41
job2 51
job2 61
job2 71
job2 81
job2 91
job2 101
1
job1 102
job1 103
job1 104
job1 105
job1 106
job1 107
job1 108
job1 109
job1 110
出现乱码,加 lock 后代码为
import threading
def job1():
global A,lock
lock.acquire() #上锁
for i in range(10):
A+=1
print('job1',A)
lock.release() #将锁打开
def job2():
global A,lock
lock.acquire()
for i in range(10):
A+=10
print('job2',A)
lock.release()
if __name__=='__main__':
lock=threading.Lock()
A=0
t1=threading.Thread(target=job1)
t2=threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
此时结果为
RESTART: C:\Users\Administrator\AppData\Local\Programs\Python\Python36\4.py
job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110
问(来自莫凡视频下的评论):这里把
t1=threading.Thread(target=job1)
t2=threading.Thread(target=job2)
改成
t1=threading.Thread(target=job1())
t2=threading.Thread(target=job2())
同样能达到 lock 的效果???