Day 20:python中几个常用的内置函数

filter(function, iterable) 

过滤器,过滤掉不满足函数 function 的元素,重新返回一个新的迭代器。

可以如下自定义过滤器函数,实现针对男女性身高筛选:

复制代码
# filter过滤器
def filter_self(function, iterable):
    return iter([ item for item in iterable if function(item)])

class Student():
    def __init__(self,name,sex, height):
        self.name = name
        self.sex = sex
        self.height = height

def height_condition(stu):
    if stu.sex == 'male':
        return stu.height > 1.75
    else:
        return stu.height > 1.65

students = [Student('xiaoming','male',1.74),
           Student('xiaohong','female',1.68),
           Student('xiaoli','male',1.80)]
students_satisfy = filter_self(height_condition,students)
for stu in students_satisfy:
    print(stu.name)
type(students_satisfy)

output:
xiaohong
xiaoli
list_iterator
复制代码

python中内置的函数filter(func, iter)如下:

复制代码
students_satisfy = filter(height_condition,students)
for stu in students_satisfy:
    print(stu.name)
type(students_satisfy)

output:
xiaohong
xiaoli
filter
复制代码
  • type(students_satisfy) 返回的略有不同

map(function, iterable, ...)

在c++中,map用于生成哈希表,而在python中,map将function 映射于 iterable 中的每一项,并返回一个新的迭代器。

  • 就是做一次映射,将映射结果以一个新的迭代器返回。
  • map 函数支持传入多个可迭代对象。出元素个数等于较短序列长度。

map 函数实现f(x) = x + 1:

复制代码
# map 映射函数
lst = [1,2,3,4,5,6,8]
ret = map(lambda x:x+1,lst)
print(ret)
print(list(ret))

output:
<map object at 0x6fffe0f9390>
[2, 3, 4, 5, 6, 7, 9]
复制代码

观察到定义中允许传入几个可迭代对象,表示function需要用到的几个参数,这时输出元素个数等于较短序列长度。

map函数实现f(x,y) = x*y:

ret = map(lambda x,y:x*y, [1,2,3,4,5,6,8],[5,4,3,2,1])
print(ret)
print(list(ret))

output:
<map object at 0x6fffe0f9a20>
[5, 8, 9, 8, 5]

p.s. 多记忆lambda的使用方法!

例如借助 map 函数,还能实现向量级运算,即使长度不相等也可以,输出短的size的映射结果:

复制代码
lst1 = [1,2,3,4,5,6,8]
lst2 = [8,5,2,9,3,1,7]
def vector_add(x,y):
    return list(map(lambda x,y:x+y,x,y))

vector_add(lst1,lst2)

output:
[9, 7, 5, 13, 8, 7, 15]
复制代码

reduce(function, iterable[, initializer])

不同于map实现映射功能,reduce实现 规约。

  • reduce 函数位于 functools 模块中,使用前需要先导入。
from functools import reduce
  • function函数的参数必须为2,是可迭代对象 iterable 内的连续两项。
  • 计算过程,从左侧到右侧,依次归约,直到最终为单个值并返回。

例如计算1+2+...+19:

reduce(lambda x,y:x+y,list(range(0,20)))

output:
190

 

reversed(seq)

重新生成一个反向迭代器,对输入的序列实现反转。

ret = reversed([1,2,3,4,5,6,8])
list(ret)

output:
[8, 6, 5, 4, 3, 2, 1]

sorted(iterable, *, key=None, reverse=False)

实现对序列化对象的排序,重要的是依据什么来排序!key=None, reverse=False 就此而来

key 参数和 reverse 参数必须为关键字参数,都可省略。

lst = [1,2,3,4,5,6,8,6,1]
sorted(lst,reverse=True)

output:
[8, 6, 6, 5, 4, 3, 2, 1, 1]

如果序列化对象的元素是一个字典,这时候key关键字就用得上了:

复制代码
a = [{'name':'xiaoming','age':20,'gender':'male'},
{'name':'xiaohong','age':18,'gender':'female'},
{'name':'xiaoli','age':19,'gender':'male'}]

b = sorted(a,key=lambda x: x['age'],reverse=False)
b

output:
[{'name': 'xiaohong', 'age': 18, 'gender': 'female'},
 {'name': 'xiaoli', 'age': 19, 'gender': 'male'},
 {'name': 'xiaoming', 'age': 20, 'gender': 'male'}]
复制代码

以上例子根据关键字‘age’进行排序,正序排序。

iter(object[, sentinel])

返回一个严格意义上的可迭代对象,其中,参数 sentinel 可省略。

复制代码
# iter迭代器
lst = [1,23,4,5,6,8,]
it = iter(lst)
print(type(it))
print(it)#严格的迭代器不能用print()函数打出来

print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())

output:
<class 'list_iterator'>
<list_iterator object at 0x6fffdf89470>
1
23
4
5
6
8
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-25-794a6047bc88> in <module>()
     11 print(it.__next__())
     12 print(it.__next__())
---> 13 print(it.__next__())

StopIteration: 
复制代码

it 迭代结束后,在 __next__ 时,触发 StopIteration 异常,即迭代器已经执行到最后。可以捕获来提升迭代器已经执行到最后。可以用for _ in it:  来提取iterator中的元素:

复制代码
# iter迭代器
lst = [1,23,4,5,6,8,]
it = iter(lst)
print(type(it))
print(it)#严格的迭代器不能用print()函数打出来

for _ in it:
    print(_)

output:
<class 'list_iterator'>
<list_iterator object at 0x6fffe3dc5f8>
1
23
4
5
6
8
复制代码

对象 it 要想支持以上这类结构,需要满足什么条件?

只要 iterable 对象支持可迭代协议,即自定义了 __iter__ 函数,便都能配合 for 依次迭代输出其元素。

下面将自定义对象的__iter__ 函数:

复制代码
class myIter(object):
    def __init__(self):
        self._lst = [1,2,3,4,5,6,8,5,1,13]

     #支持迭代协议(即定义有 __iter__() 函数)   
    def __iter__(self): 
         print ("__iter__ is called!!")
         return iter(self._lst)
ret = myIter()
for _ in ret:
    print(_)

output:
__iter__ is called!!
1
2
3
4
5
6
8
5
1
13
复制代码

next(iterator,[, default])

返回可迭代对象的下一个元素。和上述it.__next__()效果一样,当迭代到最后一个元素后再执行一次next()函数,就会抛出StopIteration错误。

复制代码
it = iter([5,3,4,1])
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))

output:
5
3
4
1
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-32-e71d85ab85d9> in <module>()
      4 print(next(it))
      5 print(next(it))
----> 6 print(next(it))

StopIteration: 
复制代码

例子,重新定义__iter__() 和 __next__()方法,达到通过循环语句,对某个正整数,依次递减 1,直到 0功能:

  • __next__ 名字不能变,实现定制的迭代逻辑
  • raise StopIteration:通过 raise 中断程序。
复制代码
from collections.abc import Iterator

class Decrease(Iterator):
    def __init__(self, init):
        self.init = init

    def __iter__(self):
        return self

    def __next__(self):
        while 0 < self.init:
            self.init -= 1
            return self.init
        raise StopIteration

descend_iter = Decrease(10)
for i in descend_iter:
    print(i)

output:
9
8
7
6
5
4
3
2
1
0
复制代码

enumerate(iterable, start=0) 

返回可枚举对象,也是一个迭代器。

复制代码
# enumerate返回可枚举对象,是迭代器
lst = ['a','s','d','748']
for i,value in enumerate(lst):
    print(i,value)
print(type(enumerate(lst)))

output:
0 a
1 s
2 d
3 748
<class 'enumerate'>
复制代码

 

posted @   PiaYie  阅读(54)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示