【Python程序设计】函数式编程

Alex_Shen
2022-03-31 / 0 评论 / 0 点赞 / 80 阅读 / 3,807 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-06,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 函数的参数传递:

定义一个简单的函数 sum 如下,

def sum(a, b, c): 
	print("a=%d, b=%d, c=%d"%(a,b,c)) 
	print(a+b+c)

以下哪些语句是合法的,哪些是不合法的?分别输出什么?解释原因。
a) sum((1, 2, 3))
b) sum(1, (2, 3))
c) sum(
(1,),b=2, 3)
d) sum(
(1,),b=2, c=3)
e) sum(*(1, 2),c=3)
f) sum(a=1, *(2, 3))
g) sum(b=1, *(2, 3))
h) sum(c=1, *(2, 3))

  1. sum(*(1, 2, 3))
    合法,两个参数为位置参数,将(1, 2, 3)解包后依次对应函数的三个参数
    输出:

a=1, b=2, c=3
6

  1. sum(1, *(2, 3))
    合法
    两个参数为位置参数,1对应a,(2, 3)解包后对应b,c
    输出:

a=1, b=2, c=3
6

  1. sum(*(1,), b=2,3)
    不合法
    SyntaxError: positional argument follows keyword argument
    关键字参数必须跟随在位置参数后面。python函数在解析参数时是按照顺序来的, 位置参数是必须先满足, 才能考虑其他可变参数。
    所以参数3不符合语法规则

  2. sum((1,), b=2, c=3)
    合法
    首先解析位置参数,
    (1,)解包对应a,然后解析关键词参数,b=2,c=3.
    输出:

a=1, b=2, c=3
6

  1. sum((1, 2), c=3)
    合法
    首先解析位置参数,
    (1,2)解包对应a,b,然后解析关键词参数c=3.
    输出:

a=1, b=2, c=3
6

  1. sum(a=1, (2, 3))
    不合法
    TypeError: sum() got multiple values for argument ‘a’
    首先解析位置参数,
    (2,3)解包对应a,b,然后解析关键词参数a=3.发现a有两个对应参数。

  2. sum(b=1, (2, 3))
    不合法
    TypeError: sum() got multiple values for argument ‘a’
    首先解析位置参数,
    (2,3)解包对应a,b,然后解析关键词参数b=3.发现b有两个对应参数。

  3. sum(c=1, (2, 3))
    合法
    首先解析位置参数,
    (2,3)解包对应a,b,然后解析关键词参数c=1。
    输出:

a=2, b=3, c=1
6

2. Lambda:

思考以下句子的输出,解释每句话意思,并通过实际测试验证自己
想法。

2.1. (lambda val: val ** 2)(5)
2.2. (lambda x, y: x * y)(3, 8)
2.3. (lambda s: s.strip().lower()[:2])(’ PyTHon’)

  1. (lambda val: val ** 2)(5)
    lamba函数的参数是val = 5 ,返回值是val ** 2 = 25
    所以输出是25

  2. (lambda x, y: x * y)(3, 8)
    lamba函数的参数是x = 3, y = 8 ,返回值是x * y = 3 * 8 = 24
    所以输出是24

  3. (lambda s: s.strip().lower()[:2])(’ PyTHon’)
    lamba函数的参数是s = ’ PyTHon’ ,返回值是s.strip().lower()[:2],也就是将字符串前后的空格移除并且转换为小写后,返回前两个字符py
    所以输出是py

3. Map:

使用 map 语句将以下输入,分别转化为指定的输出。

3.1. [‘12’, ‘-2’, ‘0’] --> [12, -2, 0]
3.2. [‘hello’, ‘world’] --> [5, 5]
3.3. [‘hello’, ‘world’]` --> [‘olleh’, ‘dlrow’]
3.4. range(2, 6) --> [(2, 4, 8), (3, 9, 27), (4, 16, 64), (5, 25, 125)]
3.5. zip(range(2, 5), range(3, 9, 2)) --> [6, 15, 28]

print(list(map(int, ['12', '-2', '0'])))
print(list(map(len, ['hello', 'world'])))
print(list(map(lambda s: s[::-1], ['hello', 'world'])))
print(list(map(lambda x: (x, x**2, x**3), range(2, 6))))
print(list(map(lambda x: x[0]*x[1], zip(range(2, 5), range(3, 9, 2)))))

img

4. Filter:

使用 filter 语句将以下输入,分别转化为指定的输出。

4.1. [‘12’, ‘-2’, ‘0’] --> [‘12’, ‘0’]
4.2. [‘hello’, ‘world’] --> [‘world’]
4.3. [‘technology’, ‘method’, ‘technique’] --> [‘technology’, ‘technique’]
4.4. range(20) --> [0, 3, 5, 6, 9, 10, 12, 15, 18]

print(list(filter(lambda x: int(x) >= 0, ['12', '-2', '0'])))
print(list(filter(lambda x: x[0] == 'w', ['hello', 'world'])))
print(list(filter(lambda x: x[:4] == 'tech', ['technology','method', 'technique'])))
print(list(filter(lambda x: x % 3 == 0 or x % 5 == 0, range(20))))

img

5. Reduce:

使用 reduce 语句编写函数 lcm(*nums),计算任意数量个正整数的最
小公倍数,要求只写一句 python 语句 (提示:可使用 math 模块的 gcd 函数先求出最大公约数)。

例子:
lcm(3, 5) # 15
lcm(41, 106, 12) # 26076
lcm(1, 2, 6, 24, 120, 720) # 720
lcm(3) # 3
lcm() # 如果没有向函数提供数字,可以返回值 1。

import math
from functools import reduce

def lcm(*nums):
    if not nums:
        return 1
    return reduce(lambda x, y: int(x*y/math.gcd(x, y)), nums)

print(lcm(3, 5))
print(lcm(41, 106, 12))
print(lcm(1, 2, 6, 24, 120, 720))
print(lcm(3))
print(lcm())

img

6. Iterator:

运行以下代码,观察输出并解释输出的原因。

it = iter(range(100))
67 in it # => True
print(next(it)) # => ??
print(37 in it) # => ??
print(next(it)) # => ??

*67 in it # => True*

在[1-100]种查找67,it依次向后直到it指向67,返回TRUE

*print(next(it)) # => 68*

It指向下一位,并返回值68

*print(37 in it) # => False*

在[69-100]种查找37,it依次向后,到iter尾仍然没有找到37,返回FALSE

*print(next(it)) # => StopIteration*

It已经在iter尾,所以执行next会越界,返回stopIteration

img

7. Generator:

7.1. 编写一个生成器 generate_triangles()

连续地产生三角数 1,3,6,10,… 三角数通过连续的正整数相加来生成(如 1=1,3=1+2,6=1+2+3,10=1+2+3+4,…)。

例子:
g=generate_triangles()
for _ in range(5):
print(next(g)) #输出 1,3,6,10,15

Ans用来记录累加值,i用来记录迭代轮数。
每一轮都是在前一轮ans的基础上,加当前轮数(i)。

def generate_triangles():
    ans, i = 0, 1
    while True:
        ans, i = ans+i, i+1
        yield ans	

7.2. 使用生成器 generate_triangles()

编写函数 generate_triangles_under(n),返回小于 n 的所有三角数

def generate_triangles_under(n):
    for ans in generate_triangles():
        if(ans > n):
            break
        print(ans,end=', ')

按照需求创建有限的序列,当超过n时结束生成序列。

img

0

评论区