python-哪些是可迭代对象?哪些是迭代器?迭代器和可迭代对象的区别——可迭代对象在遍历时不会发生消耗,但是迭代器会
一、迭代器和可迭代对象
1.1 哪些是可迭代对象?如何检测?
只要能用for x in X进行迭代的对象,都叫可迭代对象;检测一个对象是否是可迭代对象,可以用isinstace(seq, Iterable)语句,其中 Iterable类型在collections模块中,需要手动导入。
1.2 常见的可迭代对象、迭代器有哪些?
常见的可迭代对象,包括list, tuple, set, dict, ndarray等。
常见的迭代器,比如文件句柄对象,open()函数的返回值就是迭代器。
1.3 可迭代对象和迭代器的区别
可迭代对象不一定是迭代器,但是迭代器一定是可迭代对象;因此迭代器中包括可迭代对象没有的属性和方法,比如__next__(),这也导致迭代器可以传入next()而可迭代对象不行。
可迭代对象在遍历时不会发生消耗,但是迭代器是会发生消耗的;这句话很重要,是本文重点,也是全网文章中很少讲到的一个点。
二、对1.3中重点语句的进一步实验
2.1 文件对象中的read()、readline()、readlines()
本节主要参考以前我写的一篇文章。
先创建一个txt文件,一共有5行。
当先将第一行的内容传给line后,打印出line,然后再直接用read()读完所有内容,下一次直接没办法迭代。
with open('123.txt', 'r') as f:for line in f:print(line)print(f.read())print('Loop Ending.')# ugyiqvqivew# asaass
# sadasfa
# ggtrhtr
# adxzch
# Loop Ending.
而如果把read()注释掉,那么就会迭代5次,分别对应每一行。
with open('123.txt', 'r') as f:for line in f:print(line)# print(f.read())print('Loop Ending.')# ugyiqvqivew# Loop Ending.
# asaass# Loop Ending.
# sadasfa# Loop Ending.
# ggtrhtr# Loop Ending.
# adxzch
# Loop Ending.
本节的结论:对于迭代器——文件句柄对象,我们可用for x in X来遍历它,每一次的遍历都会导致内容的消耗,当然也可以用read()、readline()、readlines()来遍历其中的内容。
2.2 对于迭代器,普遍可以用iter()、for x in X、islice()等方法遍历
上一节讲的是迭代器中的文件句柄对象可以用read()、readline()、readlines()来遍历;那么对于迭代器,普遍存在哪些方式去遍历其中内容呢?
2.2.1 循环遍历法——for x in X
list1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(list(it)) # list函数会遍历完迭代器所有元素# 1
# 2
# 3
# [4, 5, 6]
2.2.2 下一个遍历法——next()
list1 = [1,2,3,4,5,6]it = iter(list1)# next函数仅仅遍历迭代器的一个元素,调用一次消耗一次
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3print(list(it)) # [4, 5, 6]print(next(it)) # 因为上面已经遍历完了,所以再遍历就会出异常;Exception : StopIteration
2.2.3 转换遍历法——list()、tuple()、set()、deque()、dict()
(1)转换成列表——list()
list1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(list(it)) # list函数会遍历完迭代器所有元素# 1
# 2
# 3
# [4, 5, 6]
(2)转换成元组——tuple()
list1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(tuple(it)) # tuple函数会遍历完迭代器所有元素# 1
# 2
# 3
# (4, 5, 6)
(3)转换成集合——set()
list1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(set(it)) # set函数会遍历完迭代器所有元素# 1
# 2
# 3
# {4, 5, 6}
(4)转换成队列——deque()
import collectionslist1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(collections.deque(it)) # deque函数会遍历完迭代器所有元素# 1
# 2
# 3
# deque([4, 5, 6])
(5)转换成字典——dict()
list1 = [('a',1), ('b',2), ('c',3), ('d',4)]it = iter(list1)for i,t in enumerate(it):print(t)if i == 1:print(dict(it)) # dict函数会遍历完迭代器所有元素# ('a', 1)
# ('b', 2)
# {'c': 3, 'd': 4}
2.2.4 切片遍历法——islice()
from collections import deque
import itertools
import numpy as npiterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
print(itertools.islice(it, None, 5, 2)) # 不用变量接收时,仅用print()无法完成遍历
print(list(it)) # [40, 30, 50, 46, 39, 44, 45, 67, 89, 34] ,因此输出的内容保留不变iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
print(list(itertools.islice(it, None, 5, 2))) # 不用变量接收时,但是用list完成了islice对象的遍历
print(list(it)) # [44, 45, 67, 89, 34] ,因此输出内容有所消耗iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
print(tuple(itertools.islice(it, None, 5, 2))) # 不用变量接收时,但是用tuple完成了islice对象的遍历
print(list(it)) # [44, 45, 67, 89, 34] ,因此输出内容有所消耗iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
print(set(itertools.islice(it, None, 5, 2))) # 不用变量接收时,但是用set完成了islice对象的遍历
print(list(it)) # [44, 45, 67, 89, 34] ,因此输出内容有所消耗iterable = [('a',40), ('b',30), ('c',50), ('d',46)]
it = iter(iterable)
print(dict(itertools.islice(it, None, 5, 2))) # 不用变量接收时,但是用dict完成了islice对象的遍历
print(list(it)) # [] ,因此输出内容有所消耗iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
print(deque(itertools.islice(it, None, 5, 2))) # 不用变量接收时,但是用deque完成了islice对象的遍历
print(list(it)) # [44, 45, 67, 89, 34]# <itertools.islice object at 0x0000022F09409EA0>
# [40, 30, 50, 46, 39, 44, 45, 67, 89, 34]
# [40, 50, 39]
# [44, 45, 67, 89, 34]
# (40, 50, 39)
# [44, 45, 67, 89, 34]
# {40, 50, 39}
# [44, 45, 67, 89, 34]
# {'a': 40, 'c': 50}
# []
# deque([40, 50, 39])
# [44, 45, 67, 89, 34]
切片遍历法有两种实施方式,要么直接转,要么先传给一个中间变量再转;前者在上面这一块代码,后者具体看下面的这块代码。
import itertools# 情况1:start和stop都不是None,则在区间内的元素才被消耗
iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
d = itertools.islice(it, 2, 4)
print(list(d)) # [50, 46]
print(list(it)) # [39, 44, 45, 67, 89, 34]# 情况2:stop是None,则所有元素都被消耗
iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
d = itertools.islice(it, 4, None, 2)
print(list(d))
print(list(it)) # []# 情况3:start是None,则从一开头到stop区间中的元素被消耗
iterable = [40,30,50,46,39,44,45,67,89,34]
it = iter(iterable)
d = itertools.islice(it, None, 5, 2)
print(list(d)) # [40, 50, 39]
print(list(it)) # [44, 45, 67, 89, 34]# [50, 46]
# [39, 44, 45, 67, 89, 34]
# [39, 45, 89]
# []
# [40, 50, 39]
# [44, 45, 67, 89, 34]
对于切片遍历法消耗内容的范围;如果stop设置为None,那么会遍历(消耗)所有元素;而如果start没设置为None,start往前的元素并不会被遍历(消耗)到。 详见上面的代码块。
2.3 哪些方法看起来能遍历但实际无法遍历?
2.3.1 print(iterator)函数无法遍历
list1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)# 1
# 2
# 3
# 4
# 5
# 6
2.3.2 numpy.array()或numpy.asarray()函数并无法遍历迭代器中的内容
import numpy as nplist1 = [1,2,3,4,5,6]it = iter(list1)for i in it:print(i)if i == 3:print(np.array(it)) # 返回的结果和不用np.array()的一样# 1
# 2
# 3
# <list_iterator object at 0x0000022F08FA78E0>
# 4
# 5
# 6
python-哪些是可迭代对象?哪些是迭代器?迭代器和可迭代对象的区别——可迭代对象在遍历时不会发生消耗,但是迭代器会相关推荐
- Python基础知识——函数的基本使用、函数的参数、名称空间与作用域、函数对象与闭包、 装饰器、迭代器、生成器与yield、函数递归、面向过程与函数式(map、reduce、filter)
文章目录 1 函数的基本使用 一 引入 二 定义函数 三 调用函数与函数返回值 2 函数的参数 一 形参与实参介绍 二 形参与实参的具体使用 2.1 位置参数 2.2 关键字参数 2.3 默认参数 2 ...
- 经典 Python参数传递采用的肯定是“传对象引用”的方式。相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象
python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是"传对象引用"的方式.这种方式相当于传值和传引用的一种综合.如果函数收到的是一个可变对象(比如字典或 ...
- python对象属性是与数据有关的项目_python之对象产生,属性(定义的值)的查找原则,对象绑定关系...
例1: 通过外部定义一个函数也可以传值进去 class OldboyStudent: school='oldboy' def choos ...
- java让对象分配在栈上_java – Hotspot何时可以在堆栈上分配对象?
我做了一些实验,以便了解Hotspot何时可以进行堆栈分配.事实证明,它的堆栈分配比基于available documentation的预期要有限得多.Choi"Escape Analysi ...
- 怎么确定迭代器后面还有至少两个值_学会迭代和迭代器,让你的程序更省内存...
迭代,很熟悉有很陌生,猛地一说,好多人摸不到头脑,但是在编程语言中,是常见的一种说法.今天我们就走进迭代,讲述一下迭代以及迭代器的用法. 迭代定义:通过for 循环遍历列表,元组,我们就称之为迭代! ...
- python中readlines是什么意思_python中read、readline、readlines之间的区别
读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的.读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所 ...
- python---面向对象,class参数、__init__方法、与函数区别
python-面向对象,class简介 进阶 面向对象第一节 初识class1.如何去定义一个最基本的class 2.class最基本的子元素 3.class传参 4.__init__方法 5.cla ...
- 块存储、文件存储、对象存储这三者和分布式文件存储系统的本质区别
块存储和文件存储是我们比较熟悉的两种主流的存储类型,而对象存储(Object-based Storage)是一种新的网络存储架构,基于对象存储技术的设备就是对象存储设备(Object-based St ...
- SQLServer错误:过程 sp_addextendedproperty,第 xxx 行对象无效。'dbo.xxx.xxx' 不允许有扩展属性,或对象不存在。...
上传数据库到虚拟主机,在执行SQL脚本的时候出现以下的错误: 消息 15135,级别 16,状态 8,过程 sp_addextendedproperty,第 37 行 对象无效.'dbo.Messag ...
最新文章
- 亲君圆梦,创业一起来
- vs2013突然没有代码提示功能了。
- 用Python玩转微信的正确姿势!
- excel函数公式html文档,Excel中把计算式转换为运算结果的方法 EXCEL中计算出的公式如何转换成纯文本内容?...
- 《推荐系统实践》样章:如何利用用户标签数据
- 人受失败后多久可以做第二次_做完皮秒多久可以用自己的护肤产品、过来人分享皮秒后怎么护肤?...
- 最小二乘法的几何意义
- 网盘上传文件服务器失败原因,win10系统在百度网盘上传文件一直失败的恢复教程...
- #腾讯云·未来开发者云梯计划#第三期上线啦!全国5000个免费云认证培训考试名额开放报名中!
- 教你一键开发桌面应用程序
- 厉害了!北大3位硕博生搞出ChatGPT版Excel!动动嘴就能自动处理表格……免费用!...
- 字节跳动2020届秋招笔试题
- 泰坦尼克号生存预测(超详细)
- 【google】解决google浏览器不弹出账号密码保存框且无法保存登录信息问题
- 华为设备流量抑制及风暴控制配置命令
- 用 CodeRuler 征服中世纪王国
- SAP 项目实施阶段全过程
- GD32F103C读写flash
- OpenStack floating IP
- Android开发之歪门邪道给 文本选中追加第三方软件入口