首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >通过内置对象理解 Python(十一)

通过内置对象理解 Python(十一)

作者头像
老齐
发布2021-12-21 17:55:56
发布2021-12-21 17:55:56
5760
举报
文章被收录于专栏:老齐教室老齐教室
  • 通过内置对象理解 Python(一)
  • 通过内置对象理解 Python(二)
  • 通过内置对象理解 Python(三)
  • 通过内置对象理解 Python(四)
  • 通过内置对象理解 Python(五)
  • 通过内置对象理解 Python(六)
  • 通过内置对象理解 Python(七)
  • 通过内置对象理解 Python(八)
  • 通过内置对象理解 Python(九)
  • 通过内置对象理解 Python(十)

sortedreversed:用于序列

排序和反转数据序列可能是任何编程语言中最常用的算法操作,Python 中的内置函数 sortedreversed 都用于实现这些功能。

sorted 函数对输入的数据进行排序,并返回一个排序过的 list 对象。

代码语言:javascript
复制
>>> items = (3, 4, 1, 2)
>>> sorted(items)
[1, 2, 3, 4]

它使用 Tim Peters 发明的的“TimSort”算法,Tim Peters 是最早的 Python 大师之一。

sorted 还有另外两个参数:reversekey 。当 reverse=True 时,对数据进行倒序排序;key 参数接受一个函数,该函数用于每个元素,根据每个项目的自定义属性对数据进行排序。来看看下面的代码:

代码语言:javascript
复制
>>> items = [
...   {'value': 3},
...   {'value': 1},
...   {'value': 2},
... ]
>>> sorted(items, key=lambda d: d['value'])
[{'value': 1}, {'value': 2}, {'value': 3}]
>>> names = ['James', 'Kyle', 'Max']
>>> sorted(names, key=len)  # Sorts by name length
['Max', 'Kyle', 'James']

还要注意,虽然 list.sort() 已经是对列表排序的一种方法,但 .sort() 方法只存在于列表中,而 sorted 可以接受任何可迭代对象。

reversed 函数接受任何序列类型,并返回一个生成器,它将原来对象中的成员顺序反序。

返回生成器是很好的,因为这意味着反转某些对象根本不需要额外的内存空间,比如 rangelist ,它们的反转值可以逐个生成。

代码语言:javascript
复制
>>> items = [1, 2, 3]
>>> x = reversed(items)
>>> x
<list_reverseiterator object at 0x7f1c3ebe07f0>
>>> next(x)
3
>>> next(x)
2
>>> next(x)
1
>>> next(x)
StopIteration # Error: end of generator
>>> for i in reversed(items):
...     print(i)
...
321
>>> list(reversed(items))
[3, 2, 1]

mapfilter

在 Python 中,所有东西都可能是对象,但这并不一定意味着 Python 代码需要面向对象。实际上,可以用 Python 编写非常易读的函数代码。

如果不知道什么是函数式语言或函数式代码,那么这里的概念是:所有的功能都是通过函数提供的。没有一个正式的类、对象、继承等概念。本质上,所有程序都只是操作数据片段,其方法是:将它们传递给函数并将修改后的值返回给你。

函数式编程中两个非常常见的概念是mapfilter, Python为它们提供了内置函数:

map 是一个“高阶函数”,它是将另一个函数作为参数的一个函数。 例如:

代码语言:javascript
复制
>>> def square(x):
...     return x * x
...
>>> numbers = [8, 4, 6, 5]
>>> list(map(square, numbers))
[64, 16, 36, 25]
>>> for squared in map(square, numbers):
...     print(squared)
...
64
16
36
25

map 有两个参数:函数和序列,它通过将每个元素作为输入来运行该函数,并将所有输出存储在一个新列表中。 map(square, numbers) 获取每个数字并返回一个平方数列表。

注意,我必须使用 list(map(square, numbers)),这是因为 map 本身返回一个生成器。请求这些值时,它们会被惰性地一次映射一个,例如,如果循环一个 map 对象,它会在序列的每一项上逐个运行映射函数。这意味着 map 不会存储映射值的完整列表,也不会在不需要的时候浪费时间计算额外的值。

filter 非常类似于 map ,只不过,它不是将每个值映射到一个新值,而是根据条件过滤一系列的值。

这意味着 filter 的输出将包含与输入相同的项,除了一些项可能被丢弃。例如下面的例子,过滤掉奇数。

代码语言:javascript
复制
>>> items = [13, 10, 25, 8]  
>>> evens = list(filter(lambda num: num % 2 == 0, items))  
>>> evens  
[10, 8]

一些人可能已经意识到这些函数本质上是在做与列表解析相同的事情,对的!

列表解析式基本上能实现以上操作,且可读性更强。

代码语言:javascript
复制
>>> def square(x):
...     return x * x
...
>>> numbers = [8, 4, 6, 5]
>>> [square(num) for num in numbers]
[64, 16, 36, 25]

>>> items = [13, 10, 25, 8]
>>> evens = [num for num in items if num % 2 == 0]
>>> evens
[10, 8]

至于实际中用什么方式,自己选择。

len, max, minsum :计算集中量

Python 有几个计算集中量函数,即:将一组值组合成单个结果的函数。这几个函数的应用非常简单,仅举一例:

代码语言:javascript
复制
>>> numbers = [30, 10, 20, 40]
>>> len(numbers)
4
>>> max(numbers)
40
>>> min(numbers)
10
>>> sum(numbers)
100

有三个函数可以接受任何容器数据类型,比如集合、字典甚至字符串:

代码语言:javascript
复制
>>> author = 'guidovanrossum'
>>> len(author)
14
>>> max(author)
'v'
>>> min(author)
'a'

sum 的参数必须是由数字为成员的容器,这意味着,以下操作是可行的:

代码语言:javascript
复制
>>> sum(b'guidovanrossum')
1542

把问题留给你,来弄清楚这是怎么回事?

iternext :迭代

iternext 定义了 for 循环的工作机制。

for 循环看起来像这样:

代码语言:javascript
复制
for item in mylist:   
    print(item)

它的内部实际上是这样做工作的:

代码语言:javascript
复制
mylist_iterable = iter(mylist)
while True:   
    try:        
        item = next(mylist_iterable)       
        print(item)    
    except StopIteration:      
        break

Python中的 for 循环是一个巧妙伪装的 while 循环。当遍历列表或任何其他支持迭代的数据类型时,只是意味着它理解 iter 函数,并返回一个“迭代器”对象。

Python 中的迭代器对象做两件事:

  • 每次执行 next 时,都会产生新的值
  • 当迭代器的值用完时,它们会抛出 StopIteration 内置异常。

这就是 for 循环的工作原理。

顺便说一下,生成器也遵循迭代器协议:

代码语言:javascript
复制
>>> gen = (x**2 for x in range(1, 4))
>>> next(gen)
1
>>> next(gen)
4
>>> next(gen)
9
>>> next(gen)
Error: StopIteration

未完,待续

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • sorted 、 reversed:用于序列
  • map 和 filter
  • len, max, min 和 sum :计算集中量
  • iter 和 next :迭代
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档