前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python迭代器还可以这样玩

Python迭代器还可以这样玩

作者头像
somenzz
发布2020-11-25 14:46:27
3470
发布2020-11-25 14:46:27
举报
文章被收录于专栏:Python七号Python七号

十一这几天基本在家周边玩,万象汇、格林公园、肖甸湖、师弟的婚宴,空了就看看极客时间,玩玩游戏,刷刷微信,就这么过去了,此外每周五天五公里的跑步,依然在坚持。

最近发现了迭代器的一个妙招,忍不住分享给爱学习的你。

关于可迭代对象,迭代器,生成器的定义和理解,可以参考前文Python基础系列--可迭代对象、迭代器与生成器

简而言之,它们的关系可以使用下图表示:

知乎上看到这样一个图,更形象:

下面我们来做一道算法题:

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/is-subsequence

要解决这个问题,常规算法是贪心算法,维护两个指针 Ps,Pt 分别指向两个字符串 s,t 的最开始,然后对字符串 t 一路扫过去,如果某个字符和 Ps 一样,那么就把 Ps 指针前进一步,当 Ps 移出字符串 s 的最后一个字符的时候,返回 True,否则返回 False。

不过,这个代码写下来怎么也得 10 行左右。

如果使用迭代器和生成器,两行就搞定了:

代码语言:javascript
复制
>>> def is_subseq(s,t):
...     t = iter(t)
...     return all(i in t for i in s)
... 
>>> is_subseq('ace','abcde')
True
>>> is_subseq('aec','abcde')
False
>>> 

如果你一眼就看穿代码背后的逻辑,那说明已经是资深的 Python 工程师了,如果是一头雾水,那么我们把代码展开一步一步看:

首先,将原字符串变成一个迭代器:

代码语言:javascript
复制
>>> t = 'abcde'
>>> iter(t)
<str_iterator object at 0x7fa7f22c8a60>
>>> t = iter(t)
>>> t
<str_iterator object at 0x7fa7f229d4c0>

然后遍历子字符串,依次判断每个字符是否在上述的迭代器 t 中:

代码语言:javascript
复制
(i in t for i in s)

一般的的思维定势:i 必然在 t 中,因为字串 aec 的每个字符都存在于原字符串 abcde 中。

妙就妙在在这个 in 操作,in 操作判断一个字符是否在一个迭代器中,肯定是要遍历这个迭代器的,而遍历就是调用迭代器的 __next__ 方法,当存在时直接返回 True,而下一次判断时继续 __next__ 而并不回到起始位置重新查找。这一点,我们可以一步一步执行 next 做实验:以 s= 'aec' 和 t = 'abcdef' 为例:

代码语言:javascript
复制
>>> t = 'abcdef'
>>> s = 'aec'
>>> t = iter(t)
>>> 'a' in t
True
>>> next(t)
'b'
>>> 'e' in t
True
>>> #此时指针已经指向 e,再调用 next 回返回 f
>>> next(t)
'f' 
>>> 'c' in t #指针已经指向 f,f 后面不会出现字符 c,必然返回 false 
False

看到这里,相信你已经明白了,in 操作返回 True 之后,下一次再 in 判断时,是从上一次结束的位置开始查找,换句话说,在循环里面用 in 来判断一个元素是否在一个迭代器中,迭代器会自动记忆上一次判断后的位置,这相当于一个隐形指针,对于解决这道问题,提供了莫大的便利。

最后的 all 函数,用来判断一个迭代器的元素是否全部为 True,如果是则返回 True,否则就返回 False。

Python 就是这么神奇而优雅。不过你一定注意,面试的时候尽量不要用这种技巧,因为你的面试官有可能并不知道生成器的用法,这个技术知识点上,在实际工作的应用上,你已经比很多人更加熟练了。

Python七号,做更满意的七号,每周学习一个 Python 技巧,欢迎关注。

(完)

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

本文分享自 Python七号 微信公众号,前往查看

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

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

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