迭代器是23种设计模式中最常用的一种。在Python中随处可见。我们经常使用它,但不一定意识到它的存在。在一系列关于迭代器的文章中(参见文章末尾的链接),我提到了至少23种生成迭代器的方法。有些方法是专门用来生成迭代器的,有些则是“偷偷”使用迭代器来解决其他问题。
在系统学习迭代器之前,我一直以为range()方法也是用来生成迭代器的,现在突然发现它只生成可迭代对象,而不是迭代器!(Python 2中的PS: range()生成列表,本文基于Python3,生成迭代对象)
所以,我有个问题:为什么range()不生成迭代器?在寻找答案的过程中,我发现对值域类型有一些误解。因此,本文将对范围有一个全面的了解,并期待与您一起学习和进步。
1.什么是range()?
其语法:range (start,stop [,step]);Start指计数起始值,默认值为0;Stop指计数结束值,但不包括stop;步长是步长,默认为1,不能为0。range()方法生成一个左闭右开的整数范围。
也就是说,作为初级生产者,range()方法生产的原料用处很大。早点把它变成迭代器无疑是多余的行为。
你觉得这个解释合理吗?欢迎和我讨论这个话题。
3.值域类型是什么?
以上是我对range()为什么不产生迭代器的回答。顺着这个思路,我研究了它产生的范围对象,发现这个范围对象也不简单。
第一个奇怪的是,它是一个不可变的序列!我从来没有注意到这一点。虽然我从来没有想过要改变range()的值,但是这个不可修改的特性让我很惊讶。
翻看文档,官方的划分是如此清晰——有三种基本的序列类型:列表、元组和范围对象。(有三种基本的序列类型:列表、元组和范围对象。)
一直没注意到这个。原来范围类型是与列表、元组状态相同的基本序列!我一直记得string是一个不可变的序列类型,但是我从来没想过这里还有另外一个不可变的序列类型。
范围序列和其他序列类型有什么区别?
常见序列支持12种操作。范围序列只支持其中的10个,不支持加法拼接和乘法重复。
那么问题来了:同样的不可变序列,为什么字符串和元组支持以上两种运算,而范围序列不支持?虽然不可变序列不能直接修改,但是我们可以把它们复制到一个新的序列中进行操作。为什么range对象连这个都不支持?
又看官方文件解释:
…due to the fact that range objects can only represent sequences that follow a strict pattern and repetition and concatenation will usually violate that pattern.原因是 range 对象仅仅表示一个遵循着严格模式的序列,而重复与拼接通常会破坏这种模式…问题的关键在于音域序列的模式。仔细想想,其实代表了一个等差数列(喵,我高中数学知识还没忘...).拼接两个等差数列或者重复一个等差数列真的不合适。这就是范围类型不支持这两种操作的原因。由此可以推断,其他的修改动作也会破坏等差数列结构,所以不应该全部修改。
4.摘要
回头看全文,我得到两个冷门的结论:range是迭代对象而不是迭代器;range对象是一个不可变的算术序列。
单纯看结论,可能没感觉,也可能说没什么大不了的。但是如果我问,为什么range不是迭代器,为什么range是不可变序列?对于这两个问题,你还能回答一个不言自明的设计思路吗?(PS:我已经决定了,如果有机会采访别人,就要问这两个问题~)
因为靶场对象的细微有趣的特点,我觉得这篇文章写得不错。本文是作为迭代器系列文章来写的,所以对迭代器的基础知识没有太多介绍。另外,还有一个特别值得单独写的迭代器,就是生成器。
1.《range range函数用法完全解读》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《range range函数用法完全解读》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guonei/1259424.html