第二章 函数

Posted on 2019-09-10 18:23  麻世骞  阅读(249)  评论(0编辑  收藏  举报

1、通过代码实现下列转换

  二进制转十进制:v = '0b1111011'

int(0b1111011)
------------------
123

  十进制转二进制:v = 18

bin(18)
------------------
0b10010

  八进制转十进制:v = '011'

int('011', 8)
------------------
9

  十进制转八进制:v = 30

oct(12)
------------------
0o14

  十六进制转十进制:v = '0x12'

int('0x12', 16)
-------------------
18

  十进制转十六进制:v = 87

hex(87)
-------------------
0x57

  

2、python递归的最大层数

  996-998

3、列举常见的内置函数

  type() : 函数如果你只有第一个参数则返回对象的类型,三个参数返回新的类型对象。

  filter() : 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。

  map() :会根据提供的函数对指定序列做映射。

  max()  :方法返回给定参数的最大值,参数可以为序列。

  min() :方法返回给定参数的最小值,参数可以为序列。

  open()  :python open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

  range() :函数可创建一个整数列表,一般用在 for 循环中。

  print() : 方法用于打印输出,最常见的一个函数。

  len()  :方法返回列表元素个数。

  list() : 方法用于将元组转换为列表。

  dict() :函数用于创建一个字典。

  str() : 函数将对象转化为适于人阅读的形式。

  float() :函数用于将整数和字符串转换成浮点数。

  reversed()  :函数返回一个反转的迭代器。

  set() : 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

  sorted() : 函数对所有可迭代的对象进行排序操作。

  sum() : 函数返回数值列的总数。

  tuple() : 元组 tuple() 函数将列表转换为元组。

4、filter、map、reduce的区别

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

map() 会根据提供的函数对指定序列做映射。

reduce() 函数会对参数序列中元素进行累积。(python3中没有reduce函数,需要倒入functools模块)

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) ]))
--------------------------------------------------------------------------------------------------

1x1=1
2x1=2 2x2=4
3x1=3 3x2=6 3x3=9
4x1=4 4x2=8 4x3=12 4x4=16
5x1=5 5x2=10 5x3=15 5x4=20 5x5=25
6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36
7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49
8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64
9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81

6、什么是闭包

  我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。

  (内函数对外函数局部变量的引用)

7、简述生成器、迭代器、装饰器以及应用场景

  迭代器:迭代器是访问可迭代对象的工具

  生成器:生成器是一种函数,用关键字 yield 来返回值,这种函数叫生成器函数,函数被调用时会返回一个生成器对象,生成器本质上还是一个迭代器。

  装饰器:装饰器是一个在不改变原函数执行方式的前提下,给函数增添新的功能的函数。

8、-----

9、一行代码,通过filter和lambda函数输出一下列表索引为基数对应的元素。

list = [12, 213, 22, 2, 2, 2, 22, 2, 2, 32]

l2 = [12, 213, 22, 2, 2, 2, 22, 2, 2, 32]
l1 = list(filter(lambda x: x, [l2[i] for i in range(1, len(l2), 2)]))
print(l1)
---------------------------
[213, 2, 2, 2, 32]

10、------

11、请实现一个装饰器,限制该函数被调用的频率,如十秒一次。

def timer(func):
    t = 0
    def inner(*args, **kwargs):
        nonlocal t
        t2 = time.time()
        if t2 - t >= 10:
            t = time.time()
            return func(*args, **kwargs)
        else:
            print('访问间隔太短')
    return inner


@timer
def test():
    print('Hello World!!')

test()
time.sleep(9)
test()
--------------------------
Hello World!!
访问间隔太短

12、请实现一个装饰器,通过一次调用使函数一次执行5次。

def warpper(func):
    def inner(*args, **kwargs):
      for i in range(5):
          func(*args, **kwargs)

    return inner

@warpper
def test():
    print('a')

test()
-----------------------
a
a
a
a
a

13、python一行print出1~100偶数的列表。

------方法一------
l1 = [x for x in range(2, 101, 2)]
print(l1)


------方法二------
l2 = list(filter(lambda x:x % 2 == 0, range(1,101)))
print(l2)

-------------------------
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]

14、解释生成器与函数的不同,并实现和简单实用generator。

  生成器,是一种特殊的迭代器,生成器自动实现了‘迭代器协议’(__iter__和next方法),不需要再手动实现两种方法。

  函数是组织好的,可重复利用的,用来实现单一功能或者实现相关联功能的代码段。

  如果一个函数定义了关键字yield,那么这个函数将不再是一个普通的函数,而是一个generator.

def test():
    print('1')
    yield
    print('2')
    yield
    print('3')
    yield
    print('4')
test = test()
next(test)
next(test)
--------------------
1
2

15、列表推导式和生成器表达式[i % 2 for i in range(10)] 和 (i % 2 for i in range(10)) 输出结果分别是什么?

  前者生成的是一个列表,后者生成的是一个生成器。

16、map(str,[1, 2, 3, 4, 5, 6, 7, 8, 9])输出时什么?

  生成的是一个类,可以用list方法强制转化为一个列表。

l = map(str,[1, 2, 3, 4, 5, 6, 7, 8, 9])
print(l)
--------------------
<map object at 0x10cd41d68>

17、python中定义函数时如何书写可变参数和关键字参数

  可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。(*args)

  而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。(**kwargs)

18、python3.5中enumerate的意思是什么?

  对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值。

19、说说python中装饰器、迭代器的用法,描述下dict的items方法和iteritems方法的不同。

  装饰器是在不改变原函数执行方式的情况下,给函数增添新的功能的函数。

  迭代器是指遵循迭代器协议的对象,这类对象在被for循环时,每次迭代生成下一个项,不用一次生成一整个列表。

  python3中没有iteritems方法,items直接返回可迭代对象,p2中items是返回一个键值对列表,iteritems是返回一个迭代器。

20、是否使用过functools中的函数,其作用是什么?

  functools.reduce:作用是将序列中的元素进行累计。

21、符合判断一个值是函数还是方法?

  函数的格式:def关键字+函数名:,是组织好的,可重复使用的,用来实现单一或者相关联功能的代码段,提高了应用的模块性,提高了代码的重复使用率。

  被写在类中的函数就是方法。

22、请编写一个函数实现将IP地址转换成一个整数。

  如:10. 3. 9. 12转换规则为:

  10             00001010

   3             00000011

   9             00001001

  12             00001100

  再将上列二进制拼接起来计算十进制结果。

def ip_int_bin():

    inp = input('请输入一个IP地址:').strip()
    l_ip = inp.split('.')  # 将每一位放到列表中 
    s_bin = ''
    for i in l_ip:
        i_bin = '0000'+bin(int(i))[2:]
        s_bin += i_bin  # 将每一位变成二进制形式,将四位转换的二进制数进行拼接
    s_int = int(s_bin, 2)   # 将拼接后的二进制转换成十进制数
    return s_int


print(ip_int_bin())
---------------------------------------------
202116108

23、lambda表达式以及应用场景

  lambda 传入值:返回值

  python用lambda函数来创建匿名函数

24、pass的作用

  pass一般用作占位语句,是用来帮正程序结构的完整性,是一个空语句,不做任何事情。

25、*args和**kwargs

  *args是位置参数,可传入0或者多个参数,元祖形式。

  **kwargs是关键字参数,可传入0或者多个参数,字典形式。

26、如何在函数中设置一个全局变量

  global变量

27、请写出打印结果

def func(a, b = []):

    b.append(a)
    print(b)
    
    
func(1)
func(1)
func(1)
func(1)

  结果:

[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
def func(a, b = {}):
    b[a] = 'v'
    print(b)


func(1)
func(2)

  结果:

{1: 'v'}
{1: 'v', 2: 'v'}

28、求结果:lambda

def num():
    return [lambda x:x*i for i in range(4)]
print([m(2) for m in num()])

  结果:

[6, 6, 6, 6]

  解释:代码中,lambda函数属于闭包函数,它本身的命名空间中没有i,需要向外层命名空间中去请求i,外层函数是一个列表推导式函数,当lambda发出请求时,for循环中的i已经循环到3,所以,结果只能是6,

  前面i=0,i=1, i=2都没有取到。

29、简述yield 和 yield from 关键字。

  yield,使用 yield 的函数被称为生成器(generator),跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。

  yield from, yield from 后面可以跟“ 生成器 元组 列表等可迭代对象和序列,返回也是一个生成器(generator)。

  个人理解:yield把返回来的值组合成一个生成器,而yield from则把返回的(生成器,元组,列表等)组合成一个大的生成器。

30、---------------------------

31、请给出下列代码的输出结果

a = 1
def func(a):
    a = 2
func(a)
print(a)

  结果:1

  解释:函数内的是局部变量,函数外的是全局变量,函数并没有改变全局变量,两者内存地址不同,所以结果还是原来的。

b = []
def func(b):
    b.append(1)
func(b)
print(b)

  结果:[1]

  解释:函数内是将全局变量中的对象进行修改,是在原内存地址进行的操作,所以结果被修改。

32、全局变量和局部变量的区别,如何给function中的一个全局变量赋值。

  全局变量是在整个程序中声明的,整个程序都可以访问他,局部变量只是在函数内部声明,只能在函数内部访问他。

  用global 变量名 = 赋值 来在函数内给全局变量赋值。

33、什么是lambda函数,下面这段代码的输出结果是什么?

  lambda函数用于创建一个匿名函数。

nums = range(2, 20)
for i in nums:
    nums = filter(lambda x : x == i or x % i, nums)
print(nums)

  生成一个类:<filter object at 0x100a41c88>

34、指出下面程序出现的问题。

def last1lindextem(src, index):
    '''请返回传入src使用空格或者'\'切分后的倒数第index个字串'''
    return src.split('\')[-index]

  1、函数内没有内容。

  2、‘\‘没有转译

35、又一个数组[3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]请写出一个函数,找出该数组中没有重复的书的总和。

l1 = [3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]
def num_sum():
    l2 = list(set(l1))  # []
    l3 = []
    for i in l1:
        if i not in l3:
            l3.append(i)
        else:
            if i in l2:
                l2.remove(i)
    sum = 0
    for i in l2:
        sum += i
    return sum
print(num_sum())

  结果为:3

36、求打印结果

arr = [1, 2, 3]
def bar():
    arr += [5]

bar()
print(arr)

  结果:报错,因为没有传参

37、请写出一个函数,计算出如下几个字母所代表的数字

  AB-CD = EF

  EF + GH = PPP

from itertools import permutations


def find_num(i):
    if i[0] == 0 or i[2] == 0 or i[4] == 0 or i[6] == 0 or i[8] == 0:
        return

    AB = i[0] * 10 + i[1]
    CD = i[2] * 10 + i[3]
    EF = i[4] * 10 + i[5]

    if AB - CD != EF:
        return

    GH = i[6] * 10 + i[7]
    PPP = i[8] * 100 + i[8] * 10 + i[8]

    if EF + GH == PPP:
        return {'A': i[0], 'B': i[1], 'C': i[2], 'D': i[3], 'E': i[4], 'F': i[5], 'G': i[6], 'H': i[7], 'P': i[8]}

if __name__ == '__main__':
    ret = []
    for i in permutations(range(0, 10), 9):
        if find_num(i):
            ret.append(find_num(i))

    print(ret)

38、请给出下面代码片段的输出

def say_hi(func):
    def warpper(*args, **kwargs):
        print('hi')
        ret = func(*args, **kwargs)
        print('bye')
        return ret
    return warpper


def say_yo(func):
    def warpper(*args, **kwargs):
        print('yo')
        return func(*args, **kwargs)
    return warpper


@say_hi
@say_yo
def func():
    print('rock&roll')


func()

  结果:

hi
yo
rock&roll
bye

39、请简述标准库中functools.wraps的作用。

  装饰器中的原函数名是作为接受返回值的,但是装饰器中的返回值是包装器名,这样就破坏了原函数的属性,functools.wraps就是为了保留原函数的属性。

40、请给出下列代码的输出结果。

def test():
    try:
        raise ValueError('something wrong')
    except:
        print('Error occured')
        return
    finally:
        print('Done')


test()

  结果:

Error occured
Done

  解释:try是执行的正常函数,如果try中报错,就执行except,不管报错与否,都执行finally,raise是抛出一个错误,所以执行了except和finally。

41、下面的函数,哪些会输出1, 2, 3三个数字?

for i in range(3):
    print(i)
-----------------------
0
1
2

alist = [0, 1, 2]
for i in alist:
    print(i + 1)
-----------------------
1
2
3

i = 1
while i < 3:
    print(i)
    i += 1
----------------------
1
2

for i in range(3):
    print(i + 1)
----------------------
1
2
3

42、以下函数需要在其中引用一个全局变量k,请填写语句。

def fun():
    global k
    k = k + 1

43、请把下列函数转化为python lambda 匿名函数。

def add(x, y):
    return x+y

  转换后:

l = lambda x, y:x+y

44、阅读以下代码,并写出程序的输出结果。

my_dict = {'a': 0, 'b': 1}


def func(d):
    d['a'] = 1
    return d

func(my_dict)
my_dict['c'] = 2
print(my_dict)

  结果:

{'a': 1, 'b': 1, 'c': 2}

45、填空题

  有函数定义如下:请写出执行结果

def calc(a, b, c, d = 1, e = 2):
    return (a + b)*(c - d) + e

print(calc(1, 2, 3, 4, 5))  # 2
print(calc(1, 2, 3))  # 8
print(calc(1, 2))  # Error
print(calc(1, 2, 3, e=4))  # 10
print(calc(e=4, c=5, a=2, b=3))  # 24
print(calc(1, 2, 3, d=5, 4))  # Error

46、def(a, b = [])这种写法有什么陷阱?

  对list操作是,可能用的是同一个list,一旦改变丢都改变了。

47、函数 

def add_end(l=[]):
    l.append('end')
    return l


print(add_end())  # 输出什么
print(add_end())  # 再次输出结果是什么?

  结果:

['end']
['end', 'end']

48、函数参数*args,**kwargs的作用是什么?

def func(a, b, c, *args, **kwargs):
    pass

  *args:表示0或者多个位置参数,用元组形式

  **kwargs:表示0或者多个关键i参数,字典形式

49、可变参数定义*args, **kwargs的区别是什么?并且写出下面代码的输出内容。

  *args:表示0或者多个位置参数,用元组形式

  **kwargs:表示0或者多个关键i参数,字典形式

def foo(*args, **kwargs):
    print('args=', args)
    print('kwargs=', kwargs)
    print('--------------------')


if __name__ == '__main__':
    foo(1, 2, 3, 4)
    foo(a=1, b=2, c=3)
    foo(1, 2, 3, a=1, b=2, c=3)
    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)
kwargs= {'a': 1, 'b': 2, 'c': 3}
--------------------
args= ('a', 1, None)
kwargs= {'a': 1, 'b': '2', 'c': 3}
--------------------

50、请写出log实现主要功能是打印函数名

@log
def now():
    print('2013-12-25')


now()
----------------------------------
输出:
        call now()
        '2013-12-25'

  答案:

def log(func):
    def inner(*args, **kwargs):
        print('call '+ func.__name__ + '()')
        func(*args, **kwargs)
    return inner


@log
def now():
    print('2013-12-25')


now()

51、python如何定义一个函数?  

def <name>(args1, args2, ...)

52、代码运行结果

country_counter = {}


def addone(country):
    if country in country_counter:
        country_counter[country] += 1
    else:
        country_counter[country] = 1


addone('China')
addone('Japan')
addone('CHINA')
print(len(country_counter))

  答案:3

53、输出结果。

def doff(arg1, *args):
    print(type(args))

doff('abc', 'def', 'ghi')

  答案:<class 'tuple'>

def doff(arg1, *args):
    print(args)

doff('abc', 'def', 'ghi')

  答案:('def', 'ghi')

54、下面程序的输出结果是?

d = lambda p:p*2
t = lambda p:p*3

x = 2
x = d(x)
x = t(x)
x = d(x)
print(x)

  答案:24

55、什么事lambda表达式?

  格式为:lambda 输入值:输出值

  用来创建匿名函数

56、以下代码的输出是什么?请给出答案并详解。

def multipliers():
    return [lambda x:x*i for i in range(4)]

print([m(2) for m in multipliers()])

  答案:[6, 6, 6, 6]

  解释:lambda是闭包函数,它里面没有对象i,所以需要从外层函数中获取,而此时哇哦层函数中的i已经通过for循环变成值为3,所以,结果为[6, 6, 6, 6]。

57、有0<x<=10,10<x<=20, 20<x<=30,..., 190<x<=200,200<x这样的21个区间分别对应1-21二十一个级别,请编写一个函数level(x)根据输入值返回对应级别。

def level(num):
    if num < 0:
        return '超出范围,重新输入'
    elif num > 200:
        return '该数字等级为21'
    else:
        return '该数字的等级为%s级'%num//10 if num % 10 == 0 else '该数字的等级为%s级' %(num//10 + 1)


if __name__ == '__main__':
    num = input('请输入一个数字:')
    num = int(num)
    print(level(num))

58、写函数

  有一个数据结构如下所示,请编写函数从该数据结构中返回由指定的字段和对应的值组成的字典,如果制定字段不存在,则跳过。

data = {
    'time': '2016-08-05T13:13:05',
    'some_id':'ID1234',
    'grp1': {'fld1': 1, 'fld2': 2},
    'xxx2': {'fld3': 0, 'fld4': 4},
    'fld6': 11,
    'fld7': 7,
    'fld46': 8
}


def select(data, field):
    dict1 = {}
    l1 = field.split('|')
    for i in l1:
        if i in data.keys():
            dict1[i] = data[i]
    return dict1

if __name__ == '__main__':
    field = input('请输入一个字段(以abc|dfg|jkk...的格式):')
    print(select(data, field))

59、补全代码