难度指数: ★★★
重要指数: ★★★★
使用with open()的方式打开文件进行操作,如果在读或写的过程中发生了异常,with 会帮我们close文件。如果用try ... except ... finally 方式可以实现同样的效果,在finally中关闭文件。但这样写太麻烦了,不如with open 方便。
提到with ,你必须理解上下文管理器,一个对象实例实现了__enter__ 和 __exit__ 方法,那么它就是一个上下文管理器。__enter__ 通常返回实例本身,__exit__方法里可以做一些清理工作,比如文件的关闭,with 语句块里的代码就在这两个函数中间被执行。
关于with 关键字,参见文章python with 语句
难度指数: ★★
重要指数: ★★★
题目要求:
列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25]
编程题目,考察的是你的概念理解和动手能力,只有多练习,才能在面试时从容应对
lst = [1, 2, 3, 4, 5]
for item in map(lambda x: x**2, lst):
print(item)
result = [item for item in map(lambda x: x**2, lst) if item > 10]
print(result) # [16, 25]
关于列表推导式,参见文章列表生成式, 字典生成式, 集合生成式
难度指数: ★★
重要指数: ★★★
题目要求:
列表推导式求列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [item for item in a if item % 2 == 1]
print(result) # [1, 3, 5, 7, 9]
难度指数: ★★★
重要指数: ★★★
题目要求:
[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]
lst = [[1, 2], [3, 4], [5, 6]]
result = [value for item in lst for value in item]
print(result) # [1, 2, 3, 4, 5, 6]
# 等价于
reslut = []
for item in lst:
for value in item:
result.append(item)
难度指数: ★★★
重要指数: ★★★
try ... except 是捕获异常,处理异常的基本形式,except 可以有多个,以应对不同的Exception。
如果try 与 except 之间的代码没有发生异常,则进入else语句块进行处理,这种语法免去了对是否发生异常的判断。
不论是否发生异常,finally都会被执行,这是非常容易搞错的一点,哪怕前面的语句执行了return, finally也会执行,因此finally语句块里通常放善后处理的代码,因为一定会被执行。
try:
0/0
except ValueError:
print("ValueError")
except AttributeError:
print("AttributeError")
else:
print('没有异常')
finally:
print("一定被执行")
难度指数: ★★★
重要指数: ★★★
这是一个非常经典的面试题,第一种解法
a = 3
b = 4
a = a + b # a = 7 b = 4
b = a - b # b = 7 - 4 = 3 a = 7
a = a - b # a = 7 - 3 = 4
print(a, b) # 4 3
不借助第三个变量,实现了两个变量值的交换。
对于python而言,完全不需要这样复杂
a = 3
b = 4
a, b = b, a
print(a, b)
难度指数: ★★★★
重要指数: ★★★★★
copy 是浅拷贝,deepcopy 是深拷贝,python中有一个copy模块,提供了这两个方法。
关于深拷贝和浅拷贝,我们主要从是否生成新的对象这个层面来进行比较。
浅拷贝
深拷贝
关于深拷贝与浅拷贝,想要深入理解,参见文章深拷贝与浅拷贝
难度指数: ★★★★
重要指数: ★★★★★
可迭代对象概念
想要理解迭代器,首先要理解什么是可迭代对象,平时比较常用的数据类型,例如列表,元组,字符串,字典,集合都是可迭代对象,一个对象实现了__iter__ 方法,那么它就是一个可迭代对象。
iter函数的作用
iter函数作用于可迭代对象时,返回一个迭代器
from collections import Iterable, Iterator
lst = [1, 2, 3]
print(isinstance(lst, Iterable), isinstance(lst, Iterator)) # True, False
_iter = iter(lst) # iter函数返回迭代器
print(isinstance(_iter, Iterator)) # True
next函数的作用
next函数可以从迭代器中取出数据,这个过程是不可逆的,已经取出的数据不能再被取出,执行next的过程就是迭代的过程,游标从头迭代到尾部
lst = [1, 2, 3]
_iter = iter(lst)
print(next(_iter)) # 1
print(next(_iter)) # 2
print(next(_iter)) # 3
print(next(_iter)) # 引发异常 StopIteration
当没有数据可以迭代时,引发StopIteration异常。
for循环与迭代器
lst = [1, 2, 3]
for item in lst:
print(item)
上面这种for循环的写法,其内部是这样执行的
这就是for循环的本质,想要解释清楚迭代器,就必须把上面这4点答出来
难度指数: ★★★★
重要指数: ★★★★★
关键点:
生成器函数
如果一个函数内部出现了yield这个关键字,那么该函数就是一个生成器函数,调用生成器函数将得到一个生成器
def my_generator(n):
index = 0
while index < n:
yield index
index += 1
generate = my_generator(5)
print(type(generate))
for i in generate:
print(i)
生成器表达式
squares = (x**2 for x in range(5))
print type(squares)
关于生成器更详细的介绍,参见文章python 生成器
难度指数: ★★
重要指数: ★★
[i for i in range(3)] 是一个列表推导式,改成生成式也非常简单
_iter = (i for i in range(3))
print(type(_iter)) # <class 'generator'>
难度指数: ★
重要指数: ★
python中并没有三元运算符,但可以通过if 语句来伪装出一个三元运算表达式
a = 4
b = 3
result = True if a > 3 else False
print(result) # True
难度指数: ★★★
重要指数: ★★★
实现了__enter__() 和__exit__()的对象就是上下文管理器
下面是一个上下文管理器的例子
import time
class ProTime(object):
def __init__(self, tag=''):
self.tag = tag
def __enter__(self):
self.start_time = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end_time = time.time()
time_diff = self.end_time - self.start_time
msg = "代码段{tag}运行时长{time_diff}".format(tag=self.tag, time_diff=time_diff)
print(msg)
with ProTime('first') as pt:
# 这里是你要统计运行时长的代码块
time.sleep(1)
with ProTime('second') as pt:
# 这里是你要统计运行时长的代码块
time.sleep(2)
运行到with 语句时,先执行__enter__()方法,通常这个方法会返回self对象,也就是as 后面的pt, 之后执行with语句块里的代码,从with语句块中退出时,则来执行__exit__()方法。
上面的上下文管理器,在进入with语句时记录时间,在退出with语句时再次记录时间,这样就可以计算出with语句块中的代码执行时长。
QQ交流群: 211426309