Python四种常用的高阶函数,你会用了吗

Posted 码同学软件测试

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python四种常用的高阶函数,你会用了吗相关的知识,希望对你有一定的参考价值。

1、什么是高阶函数

把函数作为参数传入,这样的函数称为高阶函数

例如:

def func1(x,y,f):

return f(x) + f(y)

num = func1(-10, 2, abs)

print(num)

注意:

把函数作为参数传入的时候,不要再传入函数后面解括号,

abs代表这个取绝对值,abs()表示调用这个函数,获取他的返回值

2、常用高阶函数(map,filter,sorted,reduce)

map 映射函数

一般来说接受两个函数,第一个函数使用作用的函数,第二个参数是要作用的可迭代对象

返回值是一个迭代器

lst = [1,2,3,4,5,6,7]

lst2 = [10,100,1000,10000]

def f1(x,y):

return x + y

map后面可以接受多个可迭代对象,那传入几个可迭代对象,前面的函数就要接受几个参数

print(list(map(f1,lst,lst2)))

print(list(map(lambda x,y:x+y, lst, lst2)))

例题:

有列表[1, 2, 3, 4, 5],将所有元素转换成str: [‘1’, ‘2’, ‘3’, ‘4’, ‘5’]

lst = [1,2,3,4,5]

print(list(map(str,lst)))

filter 过滤函数

filter的第一个参数传入一个函数,第二个参数是可迭代对象,将可迭代对象里的每一个值,交给传入的函数处理,如果结果为真,就保留这个值。如果结果为假,就去掉这个值。

filter也是返回一个迭代器

例如:

去掉偶数,保留奇数[1,2,3,4,5,6,7,8,9]

print(list(filter(lambda x : x % 2, [1,2,3,4,5,6,7,8,9])))

在一个list中,删掉偶数,只保留奇数

lst=[‘A’,‘’,‘B’,None,‘C’,’ ',‘a’,1,0]

print(list(filter(lambda x:x and str(x).strip(), lst)))

sorted 排序函数

sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。

把一个序列中的字符串,忽略大小写排序

序列:[‘bob’, ‘about’, ‘Zoo’, ‘Credit’]

list1=[‘bob’,‘about’,‘Zoo’,‘Credit’]

print(sorted(list1,key=lambda x:x.lower()))

print(sorted(list1,key=str.lower))

按value来排序

d1 = “a”:3,“b”:4,“c”:2,“d”:5

print(dict(sorted(d1.items(), key=lambda x:x[1])))

列表里包的排序元素

在元组排序里为False排前面,True排后面

reduce 函数累积求值 (这个函数用的时候需要导入)

这个函数必须接收两个参数

reduce把结果继续和序列的下一个元素做累积计算

例如:

将列表[1,3,5,7,9] ---->13579

from functools import reduce

s = [1,3,5,7,9]

print(reduce(lambda x,y:x*10+y, s))

练习:

1、利用map批量检测用户名是否符合规范=> username符合规范, username不符合规范

只能包含数据、字母、下划线,不以数字开头,长度在6-18之间

filter把合法的用户名显示出来

lst = [“username”,“a123”,“Y_78ju”,“23hu”,“was23_67hu”]

import re

def func1(x):

if re.findall(r"^[a-zA-Z_][0-9a-zA-Z_]5,17$", x):

    return f"x符合规范"

else:

    return f"x不符合规范"

print(list(map(func1, lst)))

print(list(filter(lambda x:re.findall(r"1[0-9a-zA-Z_]5,17$", x), lst)))

2、 匿名函数+reduce实现 123*…*n

from functools import reduce

n=[1,2,3,4,5,6,7]

print(reduce(lambda n,y:n*y, n))

3、filter函数:找出[1-100]能被3整除的数

print(list(filter(lambda x:x%3==0, range(1,101))))

4、map函数:求list[1-10]各项的平方

print(list(map(lambda x:x*x, range(1,11))))

5、将列表[1,4,5,9] 转换成 '1459’的字符串

from functools import reduce

print(reduce(lambda x,y : str(x)+str(y),[1,4,5,9]))

6、有以下列表:

list1=[7, -8, 5, 4, 0, -2, -5]

正数在前负数在后

整数从小到大

负数从大到小

print(list(sorted(list1,key=lambda x:(x<=0, abs(x)))))

print(sorted(list1,key=lambda x: max(list1)-x+1 if x <=0 else x))

7、这是一个字符串排序,排序规则:小写<大写<奇数<偶数

s = ‘asdf234GDSdsf23’ #排序:小写-大写-奇数-偶数

原理:先比较元组的第一个值,FALSE

s = ‘asdf234GDSdsf23’

s2 = “”.join(sorted(s, key=lambda x: (x.isdigit(),x.isdigit()and int(x) % 2 == 0,x.isupper(),x)))

print(s2)

def func2(x):

return (x.isdigit() ,x.isupper(),x.isdigit() and int(x) % 2 == 0,x)

print(“”.join(sorted(s, key=func2)))

#a -->(False, False,False,‘a’)

#s -->(False, False, False,‘s’)

#2 -->(True, True, False,2)

#3 -->(True,False,False,3)

#G -->(False,False, True,“G”)


  1. a-zA-Z_ ↩︎

anynever......TypeScript 中这些特殊的类型,你会用了吗?

作者 |  geekAbyte
译者 | 弯月
出品 | CSDN(ID:CSDNnews)

以下为译文:

在本文中,我们来简要地讨论一下 TypeScript 中的三种有趣的类型:any、unknown 与 never。我们来快速了解一下这三种类型,以及何时使用它们。

首先,集合论非常适合用来分析类型系统。TypeScript 中的 Union 和 Intersection 类型就大量使用了集合论。但其思想非常简单。定义一个类型类似于定义一个集合。集合包含什么?它们包含对象。所以,对象属于一个集合。如果某个值属于某个集合,则不能在它不属于或不重叠的另一个集合中使用。

例如,类型 string 是所有字符串的集合,这个集合的数量是无限的;类型 boolean 是所有布尔值的集合,但布尔值是有限的,只有 true 和 false。基本思想就这么简单。

下面,我们来探索一下 Typescript 中的 any、unknown 与 never。


any、never......TypeScript 中这些特殊的类型,你会用了吗?

any 


any 是一种类型,它包含 Javascript 中的所有值。因此,如果你有一个值,可能来自某个没有类型注释的 Javascript 库,或者定义类型很麻烦,那么只需将其类型设置为 any 即可通过类型检查。这是因为如果把 any 当成一个集合,那么它是一个超集,包含所有值。

从理论的角度来看,any 类型被称为顶层类型(或称通用类型、通用超类型),因为所有类型的值都可以赋给它,这意味着它就是所有类型的通用类型,如下列代码所示:

let value: any;
let boolValue: boolean = truelet numValue: number = 43let strValue: string = "Hello world"
value = boolValuevalue = numValuevalue = strValue

在上述代码中,boolean、number 和 string 类型的值都可以分配给 any。Javascript 中的任何类型,甚至是自定义的类型都可以分配给 any。

然而,如果代码编写成上面这样,我们就会失去类型安全。一旦将一个值赋给 any,typescript 的编译器就无法确定原始的类型,也不清楚哪些操作是允许的,而哪些是禁止的。结果,你就不会再看到红色的波浪线或编译错误,但是原本应该在开发过程中发现的错误,就会一直留到运行时才能暴露出来。

例如:

let value: any;
let boolValue: boolean = true
value = boolValuevalue.charCodeAt(0)

在上述代码中,先是将 any 赋给了 value,然后又把一个 boolean 值赋给了它。在这之后,却用 value 调用了一个只有字符串值才能使用的方法。这是错误的,但是编译器无法指出这一点。所以,这种写法不可取。

那么,我们应该在什么时候使用 any 呢?也许在创建原型,希望尽快实现一个可行方案的时候可以使用它。你不应该在生产中使用 any,因为如果使用 any,那么一切都将失去控制。在代码库中乱用 any,就与直接使用 Javascript 没有区别了,所以即便使用了 Typescript,也不会获得类型安全的好处,最终只会让 any 注释搅得代码乱七八糟。

既然我们不能使用 any,那么有其他的替代类型吗?当然有,请参见接下来的讨论。


any、never......TypeScript 中这些特殊的类型,你会用了吗?

unknown


unknown 也是 Typescript 中的顶层类型。这意味着,所有类型的值都可以赋给 unknown 类型。

let value: unknown;
let boolValue: boolean = truelet numValue: number = 43let strValue: string = "Hello world"
value = boolValuevalue = numValuevalue = strValue

unknown 与 any 最大的区别在于,使用 unknown 的时候,编译器不允许你调用任何方法。任何方法调用都会引发编译错误,如下所示:

let value: unknown;
let boolValue: boolean = true
value = boolValue// compile errorvalue.charCodeAt(0)

这段代码就会引发编译错误。如果编译器无法确定哪些操作有效,那么就不能允许任何操作,否则就可能会产生无效操作,导致运行时出错?

其实,我们需要考虑的问题是,何时使用 unknown,以及如何使用?

只有在针对 unknown 进行类型检查后,Typescript 编译器才会允许你执行特定的操作。例如:

let value: unknown;
let boolValue: boolean = true
value = boolValue
if (typeof value === "string") { value.charCodeAt(0)}

这意味着,如果你想使用 unknown 类型的值,则必须在执行操作之前进行类型检查。这个过程被称为类型窄化(Type Narrowing)。

那么,我们应该在何时使用 unknown 呢?通常在需要使用 any,但同时又希望编译器提供类型安全的时候,就可以使用 unknown,因为编译器会强制你在调用某个方法之前,手动检查该类型是否允许这样的操作。


any、never......TypeScript 中这些特殊的类型,你会用了吗?

never


如果说 any 是顶层类型(Top type),那么 never 就是底层类型(Bottom type)这是什么意思?如果说顶层类型就是包含所有类型的值的类型,那么底层类型就是不包含任何类型的值的类型。实际上,底层类型是一个空集。

如果类型不包含任何东西,那么我们要它干什么呢?

我们可以利用 never 表示一种情况:某个永远无法返回值的操作。例如,一个永远无法返回值的函数。如下代码是一个连续输出时间戳的函数:

function neverReturns(): never { while(true) { console.log(Date.now()) }}

这个函数是什么类型?它不会返回任何值。因此,就应该将 never 类型赋给它。

在处理联合类型时,也可以使用 never。在这种情况下,never 表示不存在这种值,从而确保类型安全,如下列代码所示。

假设有一个联合类型 number | boolean 的值,我们可以使用类型窄化来编写代码,以确保该值确实为 number 或 boolean:

let value: number | boolean = 1 
function process(value: number | boolean) { if (typeof value === "number") { // TODO operate on value as number } else { // TODO operate on value as boolean }}

这种写法的问题在于,如果将来扩展 value 的联合类型,再增加一种类型,则 process 无法处理这个新类型。因此,如果将一个 boolean 值传递给函数,则在运行时会出错,而且编译器也无法发出警告。为了解决这个问题,我们可以使用 never 类型。具体的方法是再加入一个判断分支,接收输入值,并将它分配给另一个类型为 never 的值。意思是永远不会出现这种情况,如果真的出现了,则意味着判断分支中存在未处理的值。将这样的值赋给 never 类型,就会发生编译错误。我们可以通过 never 的这种使用方法来获得更多类型安全。这个过程叫做穷举类型检查,这种机制可以让我们在编译时考虑到联合类型中所有可能出现的类型。

never 类型的使用不仅限于此,还有其他很有趣的高级使用方法。但是,一般来说,never 类型的意思就是永远不包含任何值。

原文链接:https://www.geekabyte.io/2021/04/any-unknown-and-never-types-in.html

声明:本文由CSDN翻译,转载请注明来源。

any、never......TypeScript 中这些特殊的类型,你会用了吗?

4月20日晚八点,欢迎来到CSDN悦读时间直播间,与四位大咖一起探索UNIX传奇往事的启示,围观《UNIX传奇》新书发布会!

any、never......TypeScript 中这些特殊的类型,你会用了吗?