第二章 函数
1. 通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
十进制转换成二进制:v = 18
八进制转换成十进制:v = “011”
十进制转换成八进制:v = 30
十六进制转换成十进制:v = “0x12”
十进制转换成十六进制:v = 87
1 v = "0b1111011" 2 print(int(v,2)) 3 4 v = 18 5 print(oct(v)) 6 7 v = "011" 8 print(int(v,8)) 9 10 v = 30 11 print(oct(v)) 12 13 v = "0x12" 14 print(int(v,16)) 15 16 v = 87 17 print(hex(v))
2. Python 递归的最大层数?
递归官方给出的最大次数是1000次,本人实际测试994-997次
3. 列举常见的内置函数?
print() zip() map() sum() max() min() avg() abs() sorted() filter()
4. filter、map、reduce 的作用?
- filter() 相当于过滤器的作用
s=[1,2,3,5,6,8,9,10,25,12,30] # 筛选出3的倍数 # 第一个参数为一个返回True或者False的函数,第二个参数为可迭代对象 # 该函数把可迭代对象依次传入第一个函数,如果为True,则筛选 d=filter(lambda x:True if x % 3 == 0 else False,s) print(list(d))
- map()函数,
# 第一个参数为函数,依次将后面的参数传给第一个函数,并执行函数 # 如果有多个参数则,依次将后面的对应传给参数 s=map(lambda x,y:x+y,range(10),range(10)) print(list(s)) ss=map(lambda x:x*x,range(10)) print(list(ss))
- reduce()函数
from functools import reduce # 开始的时候将可迭代对象的第一个数和第二个数当成x和y # 然后将第一次函数的执行结果当成x,然后再传入一个数当成y # 再执行函数 s=reduce(lambda x,y:x+y,range(101)) print(s) # 相当于0+1+2+……+99+100
5. 一行代码实现 9*9 乘法表
print('\n'.join(['\t'.join([f"{i}x{j}={i*j}" for j in range(1,i+1)]) for i in range(1,10)]))
6. 什么是闭包?
嵌套函数内部使用外部非全局变量:
- 在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
1 # 内部函数使用了外部函数的变量,就相当于闭包 2 def func1(): 3 a=1 4 def inner(): 5 return a 6 return inner 7 print(func1()())
7. 简述 生成器、迭代器、装饰器以及应用场景?
迭代器:同时具有iter()和next()[或者说同时具有__iter__()和__next__()]方法的对象;
装饰器本质上是一个Python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能,迭代器是一个更抽象的概念,任何对象,如果它的类有next方法和iter方法返回自己本身,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIteration异常;
生成器:生成器是一种特殊的迭代器,是带有yield关键字的特殊函数,具有send()方法(第一次迭代时必须传递一个参数None),生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用 yield 语句。每次 next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值);
装饰器:对内开放对外封闭的闭包函数,以一个函数作为参数,在不改变原函数功能基础上,返回一个增加额外功能的可执行函数,装饰器的返回值也是一个函数的对象,它经常用于有切面需求的场景。 比如:插入日志、性能测试、事务处理、缓存、权限的校验等场景 有了装饰器就可以抽离出大量的与函数功能本身无关的雷同代码并发并继续使用。
8. 使用生成器编写 fib 函数, 函数声明为 fib(max), 输入一个参数 max 值, 使得该函数可以这样调用。
for i in range(0,100): print fib(1000)
并产生如下结果(斐波那契数列),1,1,2,3,5,8,13,21...
1 def fib(num): 2 a,b=0,1 3 while b<num: 4 yield b 5 a, b = b, a + b 6 for i in fib(1000): 7 print(i)
9. 一行代码, 通过 filter 和 lambda 函数输出以下列表索引为奇数对应的元素。 list_a=[12,213,22,2,2,2,22,2,2,32]
1 list_a=[12,213,22,2,2,2,22,2,2,32] 2 print([i[1] for i in filter(lambda x:x[0]%2==1,enumerate(list_a))])
10. 写一个 base62encode 函数, 62 进制。
即:0123456789AB..Zab..z(10个数字+26个大写字母+26个小写字母)。
base62encode(1)=1
base62encode(61) = z
base62encode(62)=10
1 #字母和数字的获取方式一 2 s='' 3 for i in range(10): 4 s+=str(i) 5 for i in range(65,91): 6 s+=chr(i) 7 for i in range(97,123): 8 s+=chr(i) 9 #字母和数字的获取方式二 10 import string 11 lower=string.ascii_lowercase 12 upper=string.ascii_uppercase 13 digits=string.digits 14 s=digits+upper+lower 15 16 17 def base62encode(n): 18 li=[] 19 while n: 20 n,y=divmod(n,62) 21 print(n,y) 22 li.append(s[y]) 23 return ''.join(reversed(li)) 24 print(base62encode(62))
11. 请实现一个装饰器, 限制该函数被调用的频率, 如 10 秒一次
1 import time 2 def wrapper(f): 3 t = 0 4 def inner(*args, **kwargs): 5 t_now = time.time() 6 nonlocal t 7 if t_now - t >= 10: 8 t = t_now 9 return f() 10 else: 11 print('访问过快!!!') 12 return inner 13 14 @wrapper 15 def func(): 16 print(10) 17 18 func() 19 func()
12. 请实现一个装饰器, 通过一次调用使函数重复执行 5 次。
1 import time 2 def wrapper(f): 3 def inner(*args, **kwargs): 4 for i in range(5): 5 print(f"第{i}此执行:",end='') 6 f() 7 return inner 8 @wrapper 9 def func(): 10 print(f"{time.strftime('%X')}") 11 12 func()
13. python 一行 print 出 1~100 偶数的列表, (列表推导式, filter 均可)
print([i for i in range(101) if i%2==0]) print(list(filter(lambda x:x%2==0,range(101))))
14. 解释生成器与函数的不同, 并实现和简单使用 generator.
生成器和函数的主要区别在于函数 return value,生成器 yield value同时标记或记忆point of the yield 以便于在下次调用时从标记点恢复执行。 yield 使函数转换成生成器,而生成器反过来又返回迭代器。
1 # 简单实现生成器 2 def dec(): 3 n=0 4 for i in range(10): 5 yield n 6 n+=i 7 8 for i in dec(): 9 print(i)
15. 列表推导式和生成器表达式 [i % 2 for i in range(10)] 和 (i % 2 for i inrange(10)) 输出结果分别是什么?
[i % 2 for i in range(10)]输出结果是列表。
(i % 2 for i inrange(10))输出结果是一个生成器地址,它和列表推导式类似,它一次处理一个对象,而不是一口气处理和构造整个数据结构,可以节约内存。
16. map(str,[1,2,3,4,5,6,7,8,9]) 输出是什么?
python3中输出一个生成器
17. python 中定义函数时如何书写可变参数和关键字参数?
def func(a,*args,b=1,**kwargs):
pass
18. Python3.5 中 enumerate 的意思是什么?
-
枚举的意思,同时得到可迭代对象,如列表和元组的索引和值,以元组形式返回
19. 说说 Python 中的装饰器,迭代器的用法:描述下 dict 的 items 方法与iteritems 方法的不同
装饰器是在不修改原函数的基础上添加一个功能迭代器是读取大文件时使用的python3中没有iteritemsitems和iteritems大致相同,只是items返回的是一个列表,iteritems返回的是一个迭代器
20. 是否使用过 functools 中的函数?其作用是什么?
- functools.wraps()
- 在装饰器中用过,如果不使用wraps,则原始函数的__name__和__doc__的值就会丢失
- functools.reduce()
- 第一个参数是一个函数,第二个参数是一个可迭代对象,代码如下:
# 下面代码相当于从1加到9 from functools import reduce a=reduce(lambda x,y:x+y,range(10)) print(a)
21. 如何判断一个值是函数还是方法?
- 使用type()来判断,如果是method为方法,如果是function则是函数。
- 与类和实例无绑定关系的function都属于函数(function)
- 与类和实例有绑定关系的function都属于方法
- 调用如果是隐式传参就是方法(比如self,cls),显式传参就是函数
22. 请编写一个函数实现将 IP 地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
1 def ip(ip_str): 2 return int(''.join(["%08d"%int(bin(int(i))[2:]) for i in ip_str.split('.')]),2) 3 4 print(ip('127.0.0.1'))
def ip(ip_str):
a=ip_str.split(".")
lb=[]
for i in a:
lb.append("%08d"%int(bin(int(i))[2:]))
return int(''.join(lb),2)
print(ip('127.0.0.1'))
23. lambda 表达式格式以及应用场景?
- 格式:lambda 参数列表 : 返回表达式
- 应用场景:常见的在filter,reduce以及map中使用
24. pass 的作用?
- 通常用来标记一个还未写的代码的位置,pass不做任何事情,一般用来做占位语句,保持程序结构的完整性
25. *args 和**kwargs 作用?
*args接收动态位置参数,**kwargs接收动态位置参数
26. 如何在函数中设置一个全局变量 ?
在函数中使用global关键字定义变量
27. 请写出打印结果:
1. # 例 1 2. def func(a,b=[]): 3. b.append(a) 4. print(b) 5. func(1) 6. func(1) 7. func(1) 8. func(1) 9. 10. # 例 2 11. def func(a,b={}): 12. b[a] = 'v' 13. print(b) 14. func(1) 15. func(2)
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
{1: 'v'}
{1: 'v', 2: 'v'}
28. 求结果: lambda
1. def num(): 2. return [lambda x:i*x for i in range(4)] 3. print([m(2) for m in num()])
[6,6,6,6]
29. 简述 yield 和 yield from 关键字。
yield 和yield from都是返回生成器,后者接收列表、元组、rang()等可迭代对象简化使用yield的循序,提高效率
30. 有 processFunc 变量 ,初始化为 processFunc = collapse and (lambda s:"".join(s.split())) or (lambda s:s)调用上下文如下
1. collapse = True 2. processFunc = collapse and (lambda s:" ".join(s.split())) or (lambda s:s) 3. print processFunc("i\tam\ntest\tobject !") 4. 5. collapse = False 6. processFunc = collapse and (lambda s:" ".join(s.split())) or (lambda s:s) 7. print processFunc("i\tam\ntest\tobject !")
以上代码会在控制台输出什么?
i am test object !
i am
test object !
31. 请给出下面代码的输出结果
1 a = 1 2 def fun(a): 3 a = 2 4 fun(a) 5 print a 6 7 a = [] 8 def fun(a): 9 a.append(1) 10 fun(a) 11 print a
1
[1]
32. 全局变量和局部变量的区别, 如何给 function 里面的一个全局变量赋值
全局变量可以作用在全局作用域,局部变量作用于局部作用域,在局部修改全局变量需要使用关键字global
33. 什么是 lambda 函数, 下面这段代码的输出是什么
1 nums = range(2,20) 2 for i in nums: 3 nums = filter(lambda x:x==i or x % i, nums) 4 nums
生成器<filter object at 0x076C3D90>----list(nums)==[2,3,4...19]
34. 指出下面程序存在的问题
1 def Lastllindextem(src, index): 2 '''''请返回传入 src使用空格或者"\"切分后的倒数第 index个子串''' 3 return src.split("\")[-index]
split("\")中的\需要进行转义处理
35. 有一个数组[3,4,1,2,5,6,6,5,4,3,3] 请写一个函数, 找出该数组中没有重复的数的总和. (上面数据的么有重复的总和为 1+2=3)
#方法一 def func(l): dic = {} s = 0 for i in l: if i not in dic: dic[i] = 1 else: dic[i] += 1 for k, v in dic.items(): if v == 1: s += k return s l = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3] print(func(l)) #方法二 from collections import Counter def func(l): dic = Counter(l) s = 0 for k, v in dic.items(): if v == 1: s += int(k) return s l = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3] print(func(l))
36. 求打印结果
1 arr = [1,2,3] 2 def bar(): 3 arr+=[5] 4 bar() 5 print arr
A. error B. [5] C. [1,2,3] D. [1,2,3,5]
37. 请写一个函数, 计算出如下几个字母代表的数字
AB-CD=EF
EF+GH = PPP
for A in range(1, 10): for B in range(10): if A in [B]: continue for C in range(1, 10): if C in [A, B]: continue for D in range(10): if D in [A, B, C]: continue for E in range(1, 10): if E in [A, B, C, D]: continue for F in range(10): if F in [A, B, C, D, E]: continue for G in range(1, 10): if G in [A, B, C, D, E, F]: continue for H in range(10): if H in [A, B, C, D, E, F, G]: continue for P in range(1,10): if P in [A, B, C, D, E, F, G, H]: continue if (A * 10 + B) - (C * 10 + D) == (E * 10 + F) and (E * 10 + F) + (G * 10 + H) == (P * 100 + P * 10 + P): print(A, B, C, D, E, F, G, H, P)
38. 请给出下面代码片段的输出
1 def say_hi(func): 2 def wrapper(*args,**kwargs): 3 print("HI") 4 ret = func(*args,**kwargs) 5 print("BYE") 6 return ret 7 return wrapper 8 9 def say_yo(func): 10 def wrapper(*args,**kwargs): 11 print("YO") 12 return func(*args,**kwargs) 13 return wrapper 14 15 @say_hi 16 @say_yo 17 def func(): 18 print("ROCK & ROLL") 19 20 func()
HI
YO
ROCK & ROLL
BYE
39. 请简述标准库中 functools.wraps 的作用
在使用函数装饰器时,被装饰的函数的函数名在执行过程中名称已经变成装饰器函数内部嵌套的函数名,为了保留原来被装饰的函数名称,需要使用 @functools.wraps(fn),fn为装饰器外层函数传入的被装饰的函数名
40. 请给出下面代码片段的输出
1 def test(): 2 try: 3 raise ValueError("something wrong") 4 except ValueError as e: 5 print("Error occurred") 6 return 7 finally: 8 print("Done") 9 10 11 test()
Error occurred
Done
41. 下面的函数,那些会输出 1,2,3 三个数字
1 for i in range(3): 2 print(i) 3 alist = [0, 1, 2] 4 for i in alist: 5 print(i + 1) 6 i = 1 7 while i < 3: 8 print(i) 9 i += 1 10 for i in range(3): 11 print(i + 1)
0 1 2
1 2 3
1 2
1 2 3
42. 以下函数需要在其中引用一个全局变量 k, 请填写语句
def fun():
__________
k = k+1
global k
43. 请把以下函数转化为 python lambda 匿名函数
def add(x,y):
return x+y
add = lambda x, y: x + y
44. 阅读以下代码, 并写出程序的输出结果
1 my_dict = {"a":0,"b":1} 2 def func(d): 3 d["a"]=1 4 return d 5 6 func(my_dict) 7 my_dict["c"]=2 8 print my_dict
{'a': 1, 'b': 1, 'c': 2}
45. 填空题
1 # 有函数定义如下 2 def calc(a,b,c,d=1,e=2): 3 return (a+b)*(c-d)+e 4 5 # 请分别写出以下标号代码的输出结果, 如果出错请写出 Error 6 print calc(1,2,3,4,5) # ____ 7 print calc(1,2,3) # ____ 8 print calc(1,2) # ____ 9 print calc(1,2,3,e=4) # ____ 10 print calc(e=4, c=5, a=2,b=3) # ____ 11 print calc(1,2,3, d=5,4) # ____
2 8 error 10 24 error
46. def(a, b=[])这种写法有什么陷阱?
b=[]默认参数,在函数调用没有传递时会使用形参中定义的共有列表
47. 函数
1 def add_end(l=[]): 2 l.append("end") 3 return l 4 5 add_end() # 输出什么 6 add_end() # 再次调用输出什么? 为什么
['end'] #使用默认参数列表
['end', 'end'] #使用共有的默认参数列表
48. 函数参数 *args,**kwargs 的作用是什么
def func(a,b,c=0,*args,**kwargs):
pass
*args动态接收位置参数 ** kwargs动态接收关键字参数
49. 可变参数定义 *args,**kwargs的区别是什么?并且写出下边代码的输入内容
1 def foo(*args,**kwargs): 2 print("args=",args) 3 print("kwargs=",kwargs) 4 print("-----------------") 5 6 if __name__ =='__main__': 7 foo(1,2,3,4) 8 foo(a=1,b=2,c=3) 9 foo(1,2,3,4,a=1,b=2,c=3) 10 foo("a",1,None,a=1,b="2",c=3)
args= (1, 2, 3, 4)
kwargs= {}
-----------------
args= ()
kwargs= {'a': 1, 'b': 2, 'c': 3}
-----------------
args= (1, 2, 3, 4)
kwargs= {'a': 1, 'b': 2, 'c': 3}
-----------------
args= ('a', 1, None)
kwargs= {'a': 1, 'b': '2', 'c': 3}
-----------------
50. 请写出 log 实现(主要功能时打印函数名)
1 @log 2 def now(): 3 print ("2013-12-25") 4 5 now() 6 7 #输出 8 #call now() 9 #2013-12-25
from functools import wraps
def log(func):
@wraps(func)
def inner(*args,**kwargs):
print(f"call {func.__name__}()")
return func(*args,**kwargs)
return inner
51. Python 如何定义一个函数
A. class <name>(<Type> arg1, <type> arg2, ...) B. function <name>(arg1,arg2,...)
C. def <name>(arg1, arg2,...) D. def <name>(<type> arg1, <type> arg2...)
52. 选择代码运行结果
1 country_counter ={} 2 def addone(country): 3 if country in country_counter: 4 country_counter[country ]+=1 5 else: 6 country_counter[country ]= 1 7 8 addone("China") 9 addone("Japan") 10 addone("china") 11 print len(country_counter )
A. 0 B. 1 C. 2 D. 3 E. 4
53. 选择输出结果
1 def doff(arg1,*args): 2 print type(args) 3 4 doff("applea","bananas","cherry")
A. str B. int C. tuple D. list E. dict
54. 下面程序的输出结果是
1 d = lambda p:p*2 2 t = lambda p:p*3 3 4 x = 2 5 x = d(x) 6 x = t(x) 7 x = d(x) 8 print x
24
55. 什么是 lambda 表达式?
匿名函数形如:lambda x,y:x+y 一行代码的函数
56. 以下代码输出是什么,请给出答案并解释
1 def multipliers(): 2 return [lambda x:x*i for i in range(4)] 3 4 print([m(2) for m in multipliers()])
请修改 multipliers的定义来产生期望的结果
#[6, 6, 6, 6]
def multipliers():
return (lambda x:x*i for i in range(4))
print([m(2) for m in multipliers()])
57. 有 0 < x <= 10, 10 < x <= 20, 20 < x <= 30, .,190 < x〈= 200,200 < x 这样的21 个区间分别对应 1-21 二十一个级别,请编写一个函数 level (x)根据输 入数值返回对应级别。
# 方式一 import math def level(x): if x <= 0: return None if x > 200: return 21 return math.ceil(x / 10) print(level(101)) # 方式二 def level(x): if x > 200: return 21 m, n = divmod(x, 10) return m if n == 0 else m + 1 print(level(11))
58. 写函数
有一个数据结构如下所示,请编写一个函数从该结构数据中返回由指定的字段和对应的值组成的字典。如果指定字段不存在,则跳过该字段。
1 data:{ 2 "time":"2016-08-05T13:13:05", 3 "some_id":"ID1234", 4 "grp1":{"fld1":1, "fld2":2,}, 5 "xxx2":{"fld3":0, "fld4":0.4,}, 6 "fld6":11, 7 "fld7": 7, 8 "fld46":8 9 } 10 11 #fields:由"|"连接的以 fld开头的字符串, 如 fld2|fld7|fld29 12 13 def select(data,fields): 14 return result
def select(data, fields):
result = {}
field_list = fields.split("|")
for k,v in data.items():
if k in field_list:
result[k] = data[k]
break
if type(v) is dict:
k_v = select(v,fields)
result.update(**k_v)
return result
print(select(data, "fld2|fld7|fld29"))
59. 补全代码
若要将 N个 task分配给 N个 worker同时去完成, 每个 worker分别都可以承担这 N个 task,但费用不同. 下面的程序用回溯法计算总费用最小的一种工作分配方案, 在该方案中, 为每个 worker分配 1个 task.程序中,N个 task从 0开始顺序编号, N个 worker也从 0开始顺序编号, 主要的变量说明如下:
- ci:将任务 i分配给 worker j的费用
- task[i]: 值为 0表示 task i未分配, 值为 j表示 task,i分配给 worker j
- worker[k] 值为 0表示未分配 task, 值为 1表示 worker k已分配 task;
- mincost: 最小总费用
程序
1 N=8 2 mincosr = 65535 3 worker = [] 4 task = [] 5 temp = [] 6 c = [] 7 8 def plan(k, cost): 9 global mincosr 10 if __(1)__ and cost<mincosr: 11 mincosr = cost 12 for i in xrange(N): 13 temp[i] = task[i] 14 else: 15 for i in xrange(N): 16 if worker[i] ==0 and __(2)__: 17 worker[i] = 1 18 task[k] = __(3)__ 19 plan(__(4)__,cost+c[k][i]) 20 __(5)__ 21 task[k] = 0 22 23 def main(): 24 for i in xrange(N): 25 worker.append(0) 26 task.append(0) 27 temp.append(0) 28 c.append(0) 29 for j in xrange(N): 30 print "请输入 worker"+str(i)+"完成 task" + str(j)+"的花费" 31 input_value = input() 32 c[i].append(int(input_value)) 33 plan(0,0) 34 print('\n 最小费用: '+str(mincosr)) 35 for i in xrange(N): 36 print "Task"+str(i)+"is assigned to Worker" + str(temp[i]) 37 38 if __name__ == "__main__": 39 main()
写个函数接收一个文件夹名称作为参数, 显示文件夹中文件的路径, 以及 其中包含文件夹中文件的路径。
# 方法一 import os def func(path): if os.path.isfile(path):return None paths=os.listdir(path) for i in paths: p = os.path.join(path,i) print(p) if os.path.isdir(p): func(p) func(r'C:\Users\Administrator\Desktop\tk') print('###################') # 方法二 import os def Test1(rootDir): list_dirs = os.walk(rootDir) for root, dirs, files in list_dirs: print(root,'====') for d in dirs: print(os.path.join(root, d)) for f in files: print(os.path.join(root, f)) Test1(r'C:\Users\Administrator\Desktop\tk')