1. 巧用tuple
当我们想要分割字符串,获取特定的下标对应某个值时,比如 2019-10-12
取年、月、日
date_str = '2019-10-12'
year,month,day = tuple(date_str.split('-'))
print(year,month,day)
2. 了解try except finally
基本执行顺序
try:
print("start")
raise KeyError
except KeyError as e:
# 捕获 KeyError 异常
print('Key Error')
else:
# 没有进Except时执行
print('No error')
finally:
# 最后执行
print('finally')
--------打印结果---------
start
Key Error
finally
下面看一个易错点:
def try_test():
try:
print("start")
raise KeyError
return 1
except KeyError as e:
print('Key Error')
return 2
else:
print('No error')
return 3
finally:
print('finally')
return 4
result = try_test()
print(result)
result
是几呢? 正常都会觉得是 2 。但是实际却是 4 ,因为 Python
会将整个方法执行完,将所有return
都放到栈里,最后取第一个返回, 最后压进栈里的是 finally
里的4 。 如果 finally
中没有 return
则返回2 。
3. with 上下文管理器
如何使我们自己的对象支持上下文管理器?实现两个魔法函数。
class Sample:
def __enter__(self):
print('enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 可以在此处释放资源
print('exit')
def do_something(self):
print('这里具体要处理的事情')
with Sample() as sample:
sample.do_something()
--------打印结果---------
enter
这里具体要处理的事情
exit
4. 列表的 append 和 extend
a = [1,2]
# 会把元素当一个整体加入
a.append([0,3])
print(a) # 结果 [1, 2, [0, 3]]
a = [1,2]
# 会将元素迭代后加进去 可以为任何可迭代对象
a.extend([0,3])
print(a) # 结果 [1, 2, 0, 3]
# 内部使用extend实现
a = [1,2]
a += (0,3)
print(a) # 结果 [1, 2, 0, 3]
5. 切片的一些基础用法
切片的模式
模式[start:end:step]
start默认是0 end默认为列表长度 step步长 默认1 为负数表示反向
为默认值时都可以省略
alist = [1,2,3,4,5,6,7,8,9,10,11,12,13]
print(alist[::]) # 返回包含列表所有元素的新列表
print(alist[::-1]) # 返回包含列表所有元素的逆序列 [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
print(alist[::2]) # 隔一个取一个 从第一个开始 [1, 3, 5, 7, 9, 11, 13]
print(alist[1::2]) # 隔一个取一个 从第二个开始 [2, 4, 6, 8, 10, 12]
print(alist[3:6]) # 取 第3-6 位置的元素 [4, 5, 6]
print(alist[:100]) # 结束位置自动变成列表最大 [1,2,3,4,5,6,7,8,9,10,11,12,13]
print(alist[100:]) # 返回空列表 []
# 切片赋值
alist[len(alist):] = [14,15] # 在列表的尾部增加元素
print(alist)
alist[:0] = [-2,-1] # 在列表头部增加元素
alist[3:3] = [3,4,5] #在列表中间位置插入元素
alist[:2] = [1,2] # 替换列表元素
# 删除元素
del alist[:3]
del alist[::2]
6. 实现可切片对象
实现可切片对象 切片后返回新的对象
import numbers
class Group:
def __init__(self,name,items):
self.name = name
self.items = items
def __reversed__(self):
self.items.reverse()
def __getitem__(self, item):
cls = type(self)
# 传进来的是一个切片对象
if isinstance(item , slice):
return cls(name=self.name,items=self.items[item])
# 传进来是一个int 下标
elif isinstance(item,numbers.Integral):
return cls(name=self.name, items=[self.items[item]])
def __len__(self):
return len(self.items)
def __iter__(self):
return iter(self.items)
def __contains__(self, item):
if item in self.items:
return True
else:
return False
group = Group(name='g1' , items= ['t1', 't2' , 't3'])
print(group.items) # ['t1', 't2', 't3']
sub_group = group[1:]
print(sub_group.items) # ['t1', 't2', 't3']
7. 使用bisect来维护已排序的序列
用来处理已排序的序列,用来维持已排序的序列,升序
二分查找 bisect = bisect_right
import bisect
inter_list = []
bisect.insort(inter_list,3)
bisect.insort(inter_list,2)
bisect.insort(inter_list,5)
bisect.insort(inter_list,1)
bisect.insort(inter_list,6)
print(inter_list) # [1, 2, 3, 5, 6]
8. 一些生成式
# 列表生成式
# 提取出1-20之间的奇数
l1 = [i for i in range(20) if i % 2 == 1]
print(l1) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
def handle_item(item):
return item*item
l2 = [handle_item(i) for i in range(20) if i%2 == 1]
print(l2) # [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 生成器表达式
# 这里并不会生成一个set或者tuple 而是一个generator
g1 = (i for i in range(20) if i % 2 == 1)
print(g1) # at 0x1033beeb8>
# 也可以将生成器直接转成list
l3 = list(g1)
# 字典推导式
dic = { 'a': 2 , 'b': 3 , "c": 4 }
d1 = { v:k for k,v in dic.items() }
print(d1) # {2: 'a', 3: 'b', 4: 'c'}