十二、Python杂记

12.Python杂记

12.1 用字典dict映射代替switch case语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
""" 用字典映射代替 switch case """

def get_apple():
return 'apple'

def get_meat():
return 'meat'

def get_mice():
return 'mice'

def get_default():
return 'Nothing'


animals_fruit = {'cat':get_apple,
'dog':get_meat,
'ant':get_mice}

f = animals_fruit.get('cat',get_default)()
print(f)
f1 = animals_fruit.get('horse',get_default)()
print(f1)

12.2 列表推导式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 根据列表a 推导出 a  元素平方的新list
#方法一: for循环(不再举例); 方法二:高阶函数
a = [1,2,3,4,5]
a_list = list(map(lambda x: x*x,a))
print(a_list)

#列表推倒式
a0 = [i*i for i in a ] # [1, 4, 9, 16, 25]
# ** 表示平方; 后还可加 if 进行条件控制筛选
a1 = [i**2 for i in a if i >= 3] #只对a中元素大于3的进行平方运算
print(a1) #[9, 16, 25]

a3 = (i*2 for i in a if i >= 2)#因为元组不可变所以得到的是generator 对象
print(tuple(a3)) #(4, 6, 8, 10)

#元组、集合、字典也可以进行推倒
b = {1,2,3}
b1 = {i+2 for i in b }
print(b1) # {3, 4, 5}
对字典进行推倒
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 字典的列表推倒式
animals = {'cat':1,'dog':2,'ant':3}
print(animals['cat']) # 1

# 颠倒 key 与 value 的值
a2 = {value:key for key,value in animals.items()}
print(a2) # {1: 'cat', 2: 'dog', 3: 'ant'}

#提取dict的key
a3 = [key for key,value in animals.items()]
print(a3) #['cat', 'dog', 'ant']

a4 = (key for key,value in animals.items())

##因为元组不可变所以得到的是generator 对象
print(a4) #<generator object <genexpr> at 0x01EB6900>
print(list(a4)) #['cat', 'dog', 'ant']

12.3 iterator 与 generator

迭代器

可迭代对象(iterable): 可以用 for in 进行遍历的;不一定是迭代器;
迭代器:可以被for in 循环遍历的,一定是迭代对象;
a.可以对迭代器使用next(),但是不能对list、tuple、dict使用(不受迭代器);
b.对于实例化的迭代器,它只能被遍历一次,具有一次性;
c.如果import copy,在一个实例化对象没有被遍历前,对其进行拷贝 books_copy = copy.copy(books)(浅拷贝,深拷贝:copy.deepcopy()),则拷贝对象还可以被遍历;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import copy
class Animals_group():

def __init__(self):
self.info = ['cat','dog','ant']
self.cur = 0

def __iter__(self):
return self

def __next__(self):
if self.cur >= len(self.info):
raise StopIteration
a = self.info[self.cur]
self.cur += 1
return a

anmil_list = Animals_group()
an_copy = copy.copy(anmil_list)

for anm in anmil_list:
print(anm)

# print(next(anmil_list)) # 不能再被遍历,会报错
print(next(an_copy))

生成器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'''
得到1--1000的一组数字为例
'''
# n = [i for i in range(0,1001)]
# for x in n:
# print(x)


# def gen(max):
# n = 1
# while n<max:
# print(n)
# n += 1

# print(gen(1001))

# 生成器满足了函数的通用性,解决了性能问题,
def gen(max):
n = 1
while n < max:
n += 1
yield n #保存了一种算法

g = gen(1001)
# for i in g:
# print(i)

print(next(g))
print(next(g))
print(next(g))

# 也是一个生成器
n1 = (i for i in range(0,1001))
print(type(n1)) #<class 'generator'>

12.4 None(判空操作)

a.type(None)—
b. 尽量使用形如:if a:、if not a: 的形式来判断是否为None和元素集合是否为空或False等,而不要使用if a is None的形式;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a = 'a' # F、S、F
#a = '' # S、F、F
if not a:
print('S')
else:
print('F')

if a:
print('S')
else:
print('F')

if a is None:
print('S')
else:
print('F')

None永远对应False

12.5 对象存在并不一定是True

1
2
3
4
5
6
7
8
9
10
class Test():
def __len__(self):
return 0

test = Test() #运行后会打印出 'No'

if test:
print('Y')
else:
print('No')

12.6 boollen内置函数

1
2
3
4
5
6
7
8
9
10
11
12
class Test():

def __bool__(self): #真正控制对象的bool值
print('bool called') #当被判断真假时
return False # bool 会调用次函数

def __len__(self): # 只能返回 int 和 bool
print('len called')
return 0 # 可用于class求长度??
print(bool(Test))
#True
#bool called

12.7 装饰器的副作用及解决办法

使用装饰器会改变主函数的名称, 解决方案:
a.from functools import wraps
b.在装饰器函数里调用@wraps(函数形参)
原理:
调用@wraps时会将主函数的信息复制到闭包函数内.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import time
from functools import wraps

def decorator(func):

#解决添加装饰器后,函数名和说明被改变的办法:
@wraps(func)
def wrapper():
'''
wrapper说明
'''
print(time.time())
func()
return wrapper

@decorator
def f1():
'''
函数f1()的说明
'''
print(f1.__name__)

print(help(f1)) #没加装饰器之前:f1() \n 函数f1()的说明
#加了后:wrapper() \n wrapper说明
f1() #没加装饰器之前:f1
#加了后:wrapper

分享到