range函数用法完全解读

1472 篇文章 275 订阅
订阅专栏

迭代器是 23 种设计模式中最常用的一种(之一),在 Python 中随处可见它的身影,我们经常用到它,但是却不一定意识到它的存在。在关于迭代器的系列文章中(链接见文末),我至少提到了 23 种生成迭代器的方法。有些方法是专门用于生成迭代器的,还有一些方法则是为了解决别的问题而“暗中”使用到迭代器。

在系统学习迭代器之前,我一直以为 range() 方法也是用于生成迭代器的,现在却突然发现,它生成的只是可迭代对象,而并不是迭代器! (PS:Python2 中 range() 生成的是列表,本文基于Python3,生成的是可迭代对象)

于是,我有了这样的疑问:为什么 range() 不生成迭代器呢?在查找答案的过程中,我发现自己对 range 类型的认识存在一些误区。因此,本文将和大家全面地认识一下 range ,期待与你共同学习进步。

更多Python视频、源码、资料加群531509025免费获取

1、range() 是什么?

它的语法:range(start, stop [,step]) ;start 指的是计数起始值,默认是 0;stop 指的是计数结束值,但不包括 stop ;step 是步长,默认为 1,不可以为 0 。range() 方法生成一段左闭右开的整数范围。

对于 range() 函数,有几个注意点:(1)它表示的是左闭右开区间;(2)它接收的参数必须是整数,可以是负数,但不能是浮点数等其它类型;(3)它是不可变的序列类型,可以进行判断元素、查找元素、切片等操作,但不能修改元素;(4)它是可迭代对象,却不是迭代器。

2、 为什么range()不生产迭代器?

可以获得迭代器的内置方法很多,例如 zip() 、enumerate()、map()、filter() 和 reversed() 等等,但是像 range() 这样仅仅得到的是可迭代对象的方法就绝无仅有了(若有反例,欢迎告知)。这就是我存在知识误区的地方。

在 for-循环 遍历时,可迭代对象与迭代器的性能是一样的,即它们都是惰性求值的,在空间复杂度与时间复杂度上并无差异。我曾概括过两者的差别是“一同两不同”:相同的是都可惰性迭代,不同的是可迭代对象不支持自遍历(即next()方法),而迭代器本身不支持切片(即__getitem__() 方法)。

虽然有这些差别,但很难得出结论说它们哪个更优。现在微妙之处就在于,为什么给 5 种内置方法都设计了迭代器,偏偏给 range() 方法设计的就是可迭代对象呢?把它们都统一起来,不是更好么?

事实上,Pyhton 为了规范性就干过不少这种事,例如,Python2 中有 range() 和 xrange() 两种方法,而 Python3 就干掉了其中一种,还用了“李代桃僵”法。为什么不更规范点,令 range() 生成的是迭代器呢?

关于这个问题,我没找到官方解释,以下纯属个人观点 。

zip() 等方法都需要接收确定的可迭代对象的参数,是对它们的一种再加工的过程,因此也希望马上产出确定的结果来,所以 Python 开发者就设计了这个结果是迭代器。这样还有一个好处,即当作为参数的可迭代对象发生变化的时候,作为结果的迭代器因为是消耗型的,不会被错误地使用。

而 range() 方法就不同了,它接收的参数不是可迭代对象,本身是一种初次加工的过程,所以设计它为可迭代对象,既可以直接使用,也可以用于其它再加工用途。例如,zip() 等方法就完全可以接收 range 类型的参数。

也就是说,range() 方法作为一种初级生产者,它生产的原料本身就有很大用途,早早把它变为迭代器的话,无疑是一种画蛇添足的行为。

对于这种解读,你是否觉得有道理呢?欢迎就这个话题与我探讨。

3、range 类型是什么?

以上是我对“为什么range()不产生迭代器”的一种解答。顺着这个思路,我研究了一下它产生的 range 对象,一研究就发现,这个 range 对象也并不简单。

首先奇怪的一点就是,它竟然是不可变序列!我从未注意过这一点。虽然说,我从未想过修改 range() 的值,但这一不可修改的特性还是令我惊讶。

翻看文档,官方是这样明确划分的——有三种基本的序列类型:列表、元组和范围(range)对象。(There are three basic sequence types: lists, tuples, and range objects.)

这我倒一直没注意,原来 range 类型居然跟列表和元组是一样地位的基础序列!我一直记挂着字符串是不可变的序列类型,不曾想,这里还有一位不可变的序列类型呢。

那 range 序列跟其它序列类型有什么差异呢?

普通序列都支持的操作有 12 种。range 序列只支持其中的 10 种,不支持进行加法拼接与乘法重复。

那么问题来了:同样是不可变序列,为什么字符串和元组就支持上述两种操作,而偏偏 range 序列不支持呢?虽然不能直接修改不可变序列,但我们可以将它们拷贝到新的序列上进行操作啊,为何 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 对象仅仅表示一个遵循着严格模式的序列,而重复与拼接通常会破坏这种模式…

问题的关键就在于 range 序列的 pattern,仔细想想,其实它表示的就是一个等差数列啊(喵,高中数学知识没忘…),拼接两个等差数列,或者重复拼接一个等差数列,想想确实不妥,这就是为啥 range 类型不支持这两个操作的原因了。由此推论,其它修改动作也会破坏等差数列结构,所以统统不给修改就是了。

4、小结

回顾全文,我得到了两个偏冷门的结论:range 是可迭代对象而不是迭代器;range 对象是不可变的等差序列。

若单纯看结论的话,你也许没有感触,或许还会说这没啥了不得啊。但如果我追问,为什么 range 不是迭代器呢,为什么 range 是不可变序列呢?对这俩问题,你是否还能答出个自圆其说的设计思想呢?(PS:我决定了,若有机会面试别人,我必要问这两个问题的嘿~)

由于 range 对象这细微而有意思的特性,我觉得这篇文章写得值了。本文是作为迭代器系列文章的一篇来写的,所以对于迭代器的基础知识介绍不多,另外,还有一种特殊的迭代器也值得单独成文,那就是生成器了。

为什么range不是迭代器?range到底是什么类型?
weixin_33831196的博客
01-05 4645
迭代器是 23 种设计模式中最常用的一种(之一),在 Python 中随处可见它的身影,我们经常用到它,但是却不一定意识到它的存在。在关于迭代器的系列文章中(链接见文末),我至少提到了 23 种生成迭代器的方法。有些方法是专门用于生成迭代器的,还有一些方法则是为了解决别的问题而“暗中”使用到迭代器。 在系统学习迭代器之前,我一直以为 range() 方法也是用于生成迭代器的,现在却突然发现,它生成...
python使用range函数计算一组数和的方法
09-22
主要介绍了python使用range函数计算一组数和的方法,涉及Pythonrange函数的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
python开发中range()函数用法实例分析
01-20
本文实例讲述了python开发中range()函数用法。分享给大家供大家参考,具体如下: python中的range()函数的功能很强大,所以我觉得很有必要和大家分享一下 就好像其API中所描述的: If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions 下面是我做的demo: #如果你需要遍历一个数字序列,可以是使用python中内建的函数range() #如下面要遍历一个列
Python3常见函数range()用法详解
09-18
range函数是一个用来创建算数级数序列的通用函数,这篇文章主要介绍了Python3常见函数range()用法,需要的朋友可以参考下
Python range函数用法完全解读_python range函数
最新发布
2401_84585372的博客
04-28 408
(4)不是迭代器。
python中的range()函数详解
laosao_66的博客
10-13 4209
start、stop、step 分别表示序列的起始值、终止值和步长。start 和 step 是可选参数,如果不指定则默认为 0 和 1。
python基础语法(一)range函数
Vapus的博客
06-26 2967
python基础语法(一)range函数
pythonrange函数你需要知道三件事
lw的博客
03-31 1652
pythonrange函数你需要知道三件事
Python for i in range ()用法详解
12-23
for i in range ()作用: range()是一个函数, for i in range () 就是给i赋值: 比如 for i in range (1,3): 就是把1,2依次赋值给i range () 函数的使用是这样的: range(start, stop[, step]),分别是起始、终止和步长 range(3)即:从0到3,不包含3,即0,1,2 >>> for i in range(3): print(i) 0 1 2 range(1,3) 即:从1到3,不包含3,即1,2 for i in range(1,3): print(i) 1 2 range(1,
range函数的使用
weixin_42589048的博客
04-23 3540
内置函数range() 1,用于生成一个整数序列 2,创建range对象的三种方式 range(stop) 创建一个(0,stop)之间的整数序列,步长为1 range(start,stop) 创建一个(start,stop)之间的整数序列,步长为1 range(start,stop,step) 创建一个(start,stop)之间的整数序列步长为step 3,返回值是一个迭代器对象 4,range类型的优点:不管range对象表示的整数序列有多长,所有...
range() 函数用法
qq_41496108的博客
09-19 5万+
range() 函数可创建一个整数列表,一般用在 for 循环中。 函数语法: range(start, stop[, step]) 参数说明: start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5); stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5 step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1) 例: range(10)
Pythonrange函数用法
热门推荐
空港
02-25 6万+
#python learning #rangePython内置函数,用作范围、区间的定义,有以下三种用法 #用法1:只有一个参数,表示从0到这个参数内的所有整数,不包括参数 ran=range(10) #定义一个list,用来将range的范围的所有数进行陈放为list形式 arr_str=list(ran) print(ran) print(arr_str) #用法2:两个参数,第一...
pythonrange函数用法
dongruan00的专栏
12-25 718
range    函数说明:range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列。 >>> range(1,5) #代表从1到5(不包含5) [1, 2, 3, 4] >>> range(1,5,2) #代表从1到5,间隔2(不包含5) [1, 3] >>&gt...
每日一课 | range()函数用法
Python大本营的博客
11-27 1226
range()函数:如果你需要遍历数字序列,可以使用内置range()函数。它会生成数列,例如:>>>for i in range(5): ... print(...
pythonrange函数用法和实例
weixin_50853979的博客
09-01 7147
begin:范围起始,从start这个数开始计数并且包括start。默认从0开始,range(3)就是range(0,3).end:范围结束,计数从end结束,但是不包括end这个数。比如range(1,4)就是(1,2,3)并没有4。step:步长,默认为1。range(2,6)就是range(2,6,1)。...
range(2,3)
07-28
range(2, 3)是一个范围对象,它包含一个元素,即2。范围对象是Python中的一种序列类型,用于表示一个连续的整数序列。在这个例子中,范围对象从2开始,但不包括3。因此,它只包含一个元素2。 #### 引用[.reference_title] - *1* [Pythonrange函数的使用方法](https://blog.csdn.net/hbqjzx/article/details/127481206)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [range函数python-Python|range函数用法完全解读](https://blog.csdn.net/weixin_39615991/article/details/109618590)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 吐血总结!50道Python面试题集锦(附答案) 317449
  • Python Flask Web 框架入门 201956
  • 理解 Python 的 for 循环 116006
  • python自测100题 114690
  • python读写、创建文件、文件夹等等 112614

分类专栏

  • python 1472篇
  • 程序员 22篇
  • 机器学习 12篇
  • 29篇
  • 框架 9篇
  • 深度学习 3篇
  • 爬虫 18篇

最新评论

  • python70道练习题

    長ずる: sum_num = 0 for i in range(100,401): if i % 3 == 2 and i % 5 == 3: sum_num += i print(sum_num)

  • Python中JSON模块基本使用方法

    宽度307: 一位沙发表情包

  • python70道练习题

    2401_83950345: 求出100到400之间同时满足除以3余2和除以5余3的数的和。我们用的是python。🥺🥺

  • python70道练习题

    2401_83950345: 作者大大,呜呜呜,我们老师留了一道题不会做,想请你帮忙可以吗🥹

  • Python语音识别终极指北,没错,就是指北!

    lckj2009: text = recognizer.recognize_google_cloud(audio, language='zh-CN')这个接口就是报错啊。博主,怎么办? assert os.environ.get('GOOGLE_APPLICATION_CREDENTIALS') is not None

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 当我们遇到反爬了要怎么做?注意以下几点!
  • python中引用和赋值的区别
  • 一个简单爬虫案例,用正则采集小说网站
2023年15篇
2022年25篇
2021年426篇
2020年838篇
2019年1639篇
2018年411篇
2017年19篇

目录

目录

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

聚圣源起名取名网男孩莫姓起名新开茶叶店起名夏梦狂诗曲西班牙人队花自飘零水自流歌词龙纹身的女孩百度影音起工程机械公司的名字cpufanerror恶女花魁你好李焕英高清起名炒饭店在线制作印章公司起名餐饮企业反派爱的盛世美颜我都有张爱玲100分起什麽名字邪恶帮比天高比地厚冰点还原精灵唐人街探案演员表属牛女孩儿起名取名字大全免费网上给宝宝起名阮筠庭小孩儿起名称大全起名姓付男孩取名大全洗钱聪明的一休国语3个字公司起名,三个字的公司名称大全男孩起名最后一个字用什么好淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化