声明:该博客参考深度之眼的视频课程,如有侵权请联系小编删除博文,谢谢! 若总结有所失误,还请见谅,并欢迎及时指出。
list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}] #数字类型 列表类型 元组 字典
浅拷贝
# list_3 = list_1 #错误
list_2 = list_1.copy() #或者list_1[:] \list(list_1) 均可实现浅拷贝
对拷贝前后的两列表分别进行操作
list_2[1].append(55)
print("list_1:", list_1)
print("list_2:", list_2)
list_1.append(100)
list_2.append("n")
print("list_1:", list_1)
print("list_2:", list_2)
(2)修改元素
list_1[0] = 10
list_2[0] = 20
print("list_1:", list_1)
print("list_2:", list_2)
(3)对列表型元素进行操作
list_1[1].remove(44)
list_2[1] += [55, 66]
print("list_1:", list_1)
print("list_2:", list_2)
(4)对元组型元素进行操作
list_2[2] += (8, 9)
print("list_1:", list_1)
print("list_2:", list_2)
元组是不可变的!!
(5)对字典型元素进行操作
list_2[2] += (8, 9)
print("list_1:", list_1)
print("list_2:", list_2)
深拷贝将所有层级的相关元素全部复制,完全分开,泾渭分明,避免上述问题
import copy
list_1 = [1, [22, 33, 44], (5, 6, 7), {"name": "Sarah"}] #数字类型 列表类型 元组 字典
list_2 = copy.deepcopy(list_1)
list_1[-1]["age"] = 18
list_2[1].append(55)
print("list_1:", list_1)
print("list_2:", list_2)
import time
ls_1 = list(range(1000000))
ls_2 = list(range(500))+[-10]*500
start = time.time()
count = 0
for n in ls_2:
if n in ls_1:
count += 1
end = time.time()
print("查找{}个元素,在ls_1列表中的有{}个,共{}秒".format(len(ls_2), count, round((end-start),2)))
字典
import time
d = {i:i for i in range(100000)}
ls_2 = list(range(500))+[-10]*500
start = time.time()
cunt = 0
for n in ls_2:
try:
d[n]
except:
pass
else:
count += 1
end = time.time()
print("查找{}个元素,在ls_1列表中的有{}个,共{}秒".format(len(ls_2), count, round((end-start),2)))
d = {}
通过hash()计算键的散列值
print(hash("python"))
print(hash(1024))
print(hash((1,2)))
d["age"] = 18
print(hash("age"))
第二步: 根据计算的散列值确定其在散列表中的位置
极个别时候,散列值会发生冲突,则内部有相应的解决冲突的办法
第三步: 在该位置上存入值
键值对的访问过程
d["age"]
通过紧凑数组实现字符串的存储
# 存在运算删除法
# 缺点:每次存在运算,都要从头对列表进行遍历、查找、效率低
alist = ["d", "d", "d", "2", "2", "d", "d", "4"]
s = "d"
while True:
if s in alist:
alist.remove(s)
else:
break
print(alist)
# 一次性遍历元素执行删除
alist = ["d", "d", "d", "2", "2", "d", "d", "4"]
s = "d"
for s in alist:
alist.remove(s)
print(alist)
# 解决方法:负向索引
alist = ["d", "d", "d", "2", "2", "d", "d", "4"]
s = "d"
for i in range(-len(alist), 0):
if alist[i] == s:
alist.remove(alist[i])
print(alist)
ls = [[0]*10]*5
ls
ls[0][0] = 1
ls
ls = [[0]*10 for i in range(5)]
ls
#等价如下代码
result = []
for value in iterale:
if condition:
result.append(expression)
# 求20以内奇数的平方
squares = []
for i in range(1, 21):
if i%2 == 1:
squares.append(i**2)
print(squares)
# 求20以内奇数的平方
squares = [i**2 for i in range(1, 21) if i%2 == 1]
print(squares)
支持多变量
x = [1, 2, 3]
y = [1, 2, 3]
results = [i*j for i,j in zip(x, y)]
results
支持循环嵌套
colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = ["{} {}".format(color, size) for color in colors for size in sizes]
tshirts
squares = {i: i**2 for i in range(10)}
for k,v in squares.items():
print(k, ": ", v)
解析语法构造集合(集合推导)
squares = {i**2 for i in range(10)}
squares
生成器表达式
squares = (i**2 for i in range(10))
squares
colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = ("{} {}".format(color, size) for color in colors for size in sizes)
for tshirts in tshirts:
print(tshirts)
expr1 if condition else expr2
# 将变量n的绝对值赋值给变量x
n = 10
if n >= 0:
x = n
else:
x = -n
x
n = 10
x = n if n >= 10 else -n
x
条件表达式和解析语法简单实用、运行速度相对更快
(1)采用惰性计算的方式
(2)无需一次性存储海量数据
(3)一边执行一边计算,只计算每次需要的值
(4)实际上一直在执行next()操作,直到无值可取
squares = (i**2 for i in range(1000000))
for i in squares:
pass
#求0-100的和
#无需显示存储全部数据,节省内存
sum((i for i in range(101)))
def fib(max):
ls = []
n, a, b = 0, 1, 1
while n < max:
ls.append(a)
a, b = b, a + b
n = n + 1
return ls
fib(10)
中间尝试
def fib(max):
n, a, b = 0, 1, 1
while n < max:
print(a)
a, b = b, a + b
n = n + 1
fib(10)
构造生成器函数
在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句出继续执行
def fib(max):
n, a, b = 0, 1, 1
while n < max:
yield a
a, b = b, a + b
n = n + 1
fib(10)
for i in fib(10):
print(i)
from collections import Iterable
isinstance([1, 2, 3], Iterable)
isinstance({"name": "Sarah"}, Iterable)
isinstance('python', Iterable)
(2)生成器
squares = (i**2 for i in range(5))
isinstance(squares, Iterable)
生成器不但可以用于for循环,还可以被next()函数调用
print(next(squares))
print(next(squares))
print(next(squares))
print(next(squares))
print(next(squares))
直到没有数据可取,抛出StopIteration
可以被next()函数调用并不断返回下一个值,直至没有数据可取的对象称为迭代器:Iterator
from collections import Iterator
squares = (i**2 for i in range(5))
isinstance(squares, Iterator)
(2)列表、元组、字符串、字典、集合不是迭代器
isinstance([1, 2, 3], Iterator)
可以通过iter(iterable)创建迭代器
isinstance(iter([1, 2, 3]), Iterator)
for item in Iterable 等价于:
先通过iter()函数获得可迭代对象Iterable的迭代器
然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item
当遇到StopIteration的异常后循环结束
(3)zip enumerate 等itertools里的函数是迭代器
x = [1, 2]
y = ["a", "b"]
zip(x, y)
for i in zip(x, y):
print(i)
isinistance(zip(x, y), Iterator)
for i in enumerate(numbers):
print(i)
isinstance(enumerate(number), Iterator)
(4)文件是迭代器
with open ("测试文件.txt", "r", encoding = "utf-8") as f:
print(isinstance(f, Iterator))
(5)迭代器是可耗尽的
squares = (i**2 for i in range(5))
for square in squares:
print(square)
for square in squares:
print(square)
(6)range()不是迭代器
number = range(5)
isinstance(number, Iterator)
print(len(numbers)) #有长度
print(number[0]) #可索引
print(9 in numbers) #可存在计算
next(numbers) #不可被next()调用
for number in numbers:
print(number)
不会被耗尽
可以称range()为懒序列
是一种序列
但并不包含任何内存中的内容
而是通过计算来回答问题
需求的提出
(1)需要对已开发上线的程序添加某些功能
(2)不能对程序中函数的源代码进行修改
(3)不能改变程序中函数的调用方式
比如:要统计每个函数的运行时间
函数对象
函数是python中的第一类对象
(1)可以把函数赋值给变量
(2)对该变量进行调用,可以实现原函数的功能
def square(x):
return x**2
print(type(square)) #square是function类的一个实例
pow_2 = square #可以理解成给这个函数起了一个别名pow_2
print(pow_2(5))
print(square(5))
可以将函数作为参数进行传递
def square(x):
return x**2
def pow_2(fun):
return fun
f = pow_2(square)
f(8)
def outer():
print("out is running")
def inner():
print("inner is running")
inner()
outer()
def outer():
x = 1
z = 10
def inner():
y = x+100
return y, z
return inner
f = outer() #实际上f包含了inner函数本身+outer函数的环境
print(f)
print(f.__closure__) #__closure__属性中包含了来自外部函数的信息
for i in f.__closure__:
print(i.cell_contents)
res = f()
print(res)
闭包:延伸了作用域的函数
如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包
闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)
一旦在内层函数重新定义了相同名字的变量,则变量称为局部变量
def outer():
x = 1
def inner():
x = x+100
return x
return inner
f = outer()
f()
nonlocal允许内嵌的函数来修改闭包变量
def outer():
x = 1
def inner():
nonlocal x
x = x+100
return x
return inner
f = outer()
f()
import time
def timer(func):
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
def f1():
print("f1 run")
time.sleep(1)
f1 = timer(f1) #包含inner()和timer的环境,如传递过来的参数func
f1()
语法糖
import time
def timer(func):
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer #相当于实现了 f1 = timer(f1)
def f1():
print("f1 run")
time.sleep(1)
f1()
import time
def timer(func):
def inner(*args, **kwargs):
print("inner run")
start = time.time()
func(*args, **kwargs)
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer
def f1(n): #相当于实现了 f1 = timer(f1)
print("f1 run")
time.sleep(n)
f1(2)
被装饰函数有返回值的情况
import time
def timer(func):
def inner(*args, **kwargs):
print("inner run")
start = time.time()
func(*args, **kwargs)
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return res
return inner
@timer
def f1(n): #相当于实现了 f1 = timer(f1)
print("f1 run")
time.sleep(n)
return "wake up"
res = f1(2)
print(res)
import time
def timer(method):
def outer(func):
def inner(*args, **kwargs):
print("inner run")
if method == "origin":
print("origin_inner run")
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
elif method == "double":
print("double_inner run")
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print("{}函数运行双倍用时{:.2f}秒".format(func.__name__, 2*(end-start)))
return res
return inner
return outer
@timer(method = "origin") # 相当于timer = timer(method = "origin") f1 = timer(f1)
def f1():
print("f1 run")
time.sleep(1)
@timer(method = "double") # 相当于timer = timer(method = "origin") f1 = timer(f1)
def f2():
print("f2 run")
time.sleep(1)
f1()
f2()
理解闭包是关键!
9. 何时执行装饰器
一装饰就执行,不必等调用
func_names = []
def find_function(func):
print("run")
func_names.append(func)
return func
@find_function
def f1():
print("f1 run")
@find_function
def f2():
print("f2 run")
@find_function
def f3():
print("f3 run")
for func in func_names:
print(func.__name__)
func()
print()
import time
def timer(func):
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer
def f1(): #相当于实现了 f1 = timer(f1)
print("f1 run")
time.sleep(1)
print(f1.__name__)
import time
from functools import wraps
def timer(func):
@wraps(func)
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{}函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer
def f1(): #相当于实现了 f1 = timer(f1)
print("f1 run")
time.sleep(1)
print(f1.__name__)
f1()