前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >4 Python 基础: 讲解迭代、过滤、匿名函数、排序算法四大知识点

4 Python 基础: 讲解迭代、过滤、匿名函数、排序算法四大知识点

原创
作者头像
野原测试开发
修改2019-07-24 10:43:41
5170
修改2019-07-24 10:43:41
举报
文章被收录于专栏:技术探究技术探究

本文首发于云+社区,也可关注公众号支持一下。

迭代

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。

在Python中,迭代是通过for ... in来完成的,而很多语言比如C语言,迭代list是通过下标完成的,比如Java代码

代码语言:txt
复制
for (i=0; i<list.length; i++) {
     n = list[i];
 }

可以看出,Python的for循环抽象程度要高于C的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。

list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict(字典)就可以迭代。

image.png
image.png

因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

字典迭代的方式

  • 默认情况下,dict迭代的是key。
  • 如果要迭代value,可以用for value in d.values()
  • 如果要同时迭代key和value,可以用for k, v in d.items()

字符串迭代

由于字符串也是可迭代对象,因此,也可以作用于for循环。

image.png
image.png

如何判断一个对象是可迭代对象呢?

方法是通过collections模块的Iterable类型判断:

image.png
image.png

如果要list实现下标循环怎么办?

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

image.png
image.png
image.png
image.png

迭代器

可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

image.png
image.png

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。 而使用list是永远不可能存储全体自然数的。

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象:

image.png
image.png

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用isinstance()判断一个对象是否是Iterator对象:

image.png
image.png

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

image.png
image.png

你可能会问,为什么list、dict、str等数据类型不是Iterator?

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的,例如:

代码语言:txt
复制
for x in [1, 2, 3, 4, 5]:
    pass

实际上完全等价于:

代码语言:txt
复制
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

filter过滤

Python内建的filter()函数用于过滤序列。

和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

image.png
image.png

filter(怎么过滤,过滤什么),要怎么过滤其实就是一个函数,一个规则;要过滤什就是要过滤的列表之类的。

image.png
image.png

自己定义一个函数实现一个方法的过程,比如我们下面自己写一个实现filter函数的相同功能函数。(写filter函数实现的过程,定义一个filterFn)

image.png
image.png

这里当调用for循环或则next()的时候,函数才会执行,for i in a其实是把每一个执行的next(a)给到i,然后输出出来;当调用第一步后,函数filterFn执行,其中里面的fn给到上面def定义的函数中的Fn,列表给到listIter,然后执行此函数,for循环这个列表,把每一个循环值给到item,比如第一个0时,他在下面函数中运行,判断返回true或false给上面,真则运行下面的yield返回这个值出去然后中断运行;如果是next()调用的,则需要再次调用next()才重新在yield这个位置开始运行,for循环调用的话他会一直执行到结束。

yield小理解:

image.png
image.png
image.png
image.png
代码语言:txt
复制
# dir()

# #查看所有的全局内置函数:dir(__builtins__)
image.png
image.png
代码语言:txt
复制
students = [
    {
        'name':"小红",
        'sex':'girl'
    },
    {
        'name':"小白",
        'sex':'boy'
    },{
        'name':"小hei",
        'sex':'boy'
    },{
        'name':"小qi",
        'sex':'girl'
    }
]

def fn(item):
    if item['sex']=='girl':
        return item
    else:
        return False


list(filter(fn,students)) 

#map
#reduce

#一堆旧书,擦洗的工作   [一堆需要被操作的列表] ---》自定义
#把每一本书都拿起来,都用抹布擦干净  流程--》函数--->自定义
#一堆新书 [被操作后的列表]

#map('自定义清洗流程','自定义的一堆书')===》(得到一堆你想要的书)

#filter('')
#一堆旧书
#每一本书,拿起来看,审查新不新,烂掉了就不要,这个程度,这个依据,自定义一个流程和依据
#留下一堆你想要留下的书

#filter('自定义的过滤依据',[一堆书传入进来])

def filter1(fn,L):
    nList = []
    for item in L:
        if fn(item):
            nList.append(item)
    
    return nList


def filter2(fn,L):
    for item in L:
        yield fn(item)
            

print(filter1(fn,students))
print(list(filter2(fn,students)))
image.png
image.png

匿名函数

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数。

image.png
image.png

匿名函数语法:

lambda 参数 : 返回值或者返回的表达式

image.png
image.png

关键字lambda表示匿名函数,冒号前面的x表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

  • 用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。
  • 匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
image.png
image.png

排序算法

sorted

排序算法

排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。

Python内置的sorted()函数就可以对list进行排序:

image.png
image.png
image.png
image.png
image.png
image.png

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档