赞
踩
上次说__getitem__
时已经粗略、浅显、简单说过什么是可迭代对象。下面是找到的一个比较好的科学解释:
Python
中可迭代对象(Iterable)
并不是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )
方法或__getitem__( )
方法访问。
__iter__
方法的作用是让对象可以用for … in obj
循环遍历,__getitem__( )
方法是让对象可以通过实例名[index]
的方式访问实例中的元素。老猿认为这两个方法的目的是Python实现一个通用的外部可以访问可迭代对象内部数据的接口。
一个可迭代对象是不能独立进行迭代的,Python中,迭代是通过for … in obj
来完成的。凡是可迭代对象都可以直接用for… in obj
循环访问,这个语句其实做了两件事:第一件事是调用__iter__()
获得一个可迭代器,第二件事是循环调用__next__()
。
常见的可迭代对象包括:
a) 集合数据类型,如list、tuple、dict、set、str
等;
b) 生成器(generator
),包括生成器和带yield
的生成器函数(generator function)
,下节专门介绍。
如何判断一个对象是可迭代对象呢?具体判断方法如下两种:
利用numpy
的iterable
方法
from numpy import iterable
print(iterable(实例名))
利用collections
模块的Iterable
类
from collections import Iterable
isinstance(实例名, Iterable)
以上内容均来自于CSDN
的老猿Python,确实是大师之作,讲得简略、清晰关键是还能让人看懂,大佬!
随便定义一个对象,不定义__iter__
方法:
from numpy import iterable
class MyList:
def __init__(self, len: int):
self.list = [i for i in range(len)]
self.length = len
def __repr__(self) -> str:
return f"MyList({self.length}):{self.list}"
x = MyList(10)
for i in x:
print(i)
运行结果:
显示MyList
实例是不可迭代的
定义__iter__
方法后
range(n)
from numpy import iterable class MyList: def __init__(self, len: int): self.cursor = -1 self.length = len def __iter__(self): return self def __next__(self): if self.cursor+1 < self.length: self.cursor += 1 return self.cursor else: exit(1) def __repr__(self) -> str: return f"MyList({self.length})" x = MyList(10) print(iterable(x)) for i in x: print(i)
输出为:
True
0
1
2
3
4
5
6
7
8
9
使用next()
一步一步迭代可以看的更清楚:
from numpy import iterable class MyList: def __init__(self, len: int): self.cursor = -1 self.length = len def __iter__(self): return self def __next__(self): if self.cursor+1 < self.length: self.cursor += 1 return self.cursor else: exit(1) def __repr__(self) -> str: return f"MyList({self.length})" x = MyList(10) print(iter(x)) print(next(x)) print(next(x)) print(next(x)) print(next(x)) for i in x: print(i)
输出结果为:
MyList(10)
0
1
2
3
4
5
6
7
8
9
为什么在PyTorch
中常见迭代的踪影呢?
大概是因为深度学习的模型训练往往需要很大的数据集,有时甚至以TB(1024GB)
来计算,众所周知,大多数个人电脑的内存不超过32GB,一次性把1TB那么大的数据加载到内存当中使用,显然是不现实的。
这种情况下,把需要的数据集依次分批加载到内存中进行使用明显是更优更现实的方案,这与可迭代对象的概念与定位是不谋而合的,可以断言,正是因为Python天然支持迭代,所以Python在深度学习领域的地位非其他语言可以动摇。
Dataloader
加载数据的实例:
from cgi import test from torch.utils.data import DataLoader from torchvision.transforms import ToTensor from torchvision.datasets import CIFAR10 from numpy import iterable # 使用CIFAR10参考数据集 test_set = CIFAR10(root='./torch2Learn/dataset/cifar10_data', train=False, download=True, transform=ToTensor()) # 将数据集分批载入,每批64个 test_loader = DataLoader(dataset=test_set, batch_size=64, shuffle=True, drop_last=False) print(type(test_set)) print(type(test_loader)) print(iterable(test_set)) print(iterable(test_loader)) print(iter(test_loader)) for step, item in enumerate(test_loader): imgs_arr, kinds_arr = item
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。