Python部落组织翻译,禁止转载,欢迎转发
Iterable: 可迭代的
Iterator: 迭代器
Iterable
可迭代的就是逻辑上是“一排”的东西,比如列表、字典、元组都是iterable。>>> iter([1,2,3])
>>> iter({1:2, 2:4})
>>> iter(1234)
Traceback (most recent call last):
File "", line 1, in
iter(1234)
TypeError: 'int' object is not iterable
对于列表iter()返回一个可迭代列表的对象,对于字典它返回字典的键的可迭代对象。其他类型就会报错了。
那将iter()用于用户定义的类型,会是什么结果?
假设我们定义了一个类Stringlass String(object):
def __init__(self, val):
self.val = val
def __str__(self):
return self.val
它是可迭代的吗?
st = String('sample string')
iter(st)
TypeError: 'String' object is not iterable
你现在可能有了新问题:如何让用户定义的类可迭代
iter()内部做了什么?
我们来扩展一下刚刚定义的类class String(object):
def __init__(self, val):
self.val = val
def __str__(self):
return self.val
def __iter__(self):
print "This is __iter__ method of String class"
return iter(self.val) #self.val is python string so iter() will return it's iterator
> st = String('Sample String')
>>> iter(st)
This is __iter__ method of String class
我们添加了一个方法__iter__,它就可迭代了。这意味着iter(iterable)实际上内部是这样调用的iterable.__iter__()
等一下,添加__iter__并不是唯一的方式class String(object):
def __init__(self, val):
self.val = val
def __str__(self):
return self.val
def __getitem__(self, index):
return self.val[index]
st = String('Sample String')
>>> iter(st)
添加__getitem方法也是可以的。__iter__和__getitem__同时存在时,__iter__优先生效。
自动迭代
For循环完成自动迭代for x in iterable:
print x
没有For循环我们如何模拟这个过程def iterate_while(iterable):
index = 0
while(i< len(iterable)):
print iterable[i]
i +=1
这个办法对list和string有效,但是对字典无效,很显然它不是一个pythonic的办法。它也没有实现For循环的功能。
我们先看看Iterator,再回来解决这个问题。
Iterator
iterator对象在迭代过程中提供返回的值。它的next()或者__next__()方法用来产生这个值。
迭代结尾它会产生StopIteration异常。
iter函数为一个可迭代对象返回一个迭代器。
如果给iter函数传入一个迭代器,它就直接返回那个迭代器。
我们试着模拟For循环def simulate_for_loop(iterable):
it = iter(iterable)
while(True):
try:
print next(it)
except StopIteration:
break
late_for_loop([23,12,34,56])
23
12
34
56
一个迭代器的逻辑大概是这样的class Iterator:
def __init__(self, iterable)
self.iterable = iterable
def __iter__(self): #iter should return self if called on iterator
return self
def next(self): #Use __next__() in python 3.x
if condition: #it should raise StopIteration exception if no next element is left to return
raise StopIteration
掌握这些基础知识就够了,我们编程中应该用不到更多的知识了。
List iterator
面试的时候你可能需要写这个,所以,注意class list_iter(object):
def __init__(self, list_data):
self.list_data = list_data
self.index = 0
def __iter__(self):
return self
def next(self): #Use __next__ in python 3.x
if self.index < len(self.list_data):
val = self.list_data[self.index]
self.index += 1
return val
else:
raise StopIteration()
让我们用list_iter定义列表的iterable
class List(object):
def __init__(self, val):
self.val = val
def __iter__(self):
return list_iter(self.val)>> ls = List([1,2,34])
>>> it = iter(ls)
>>> next(it)
1
>>> next(it)
2
>>> next(it)
34
>>> next(it)
Traceback (most recent call last):
File "", line 1, in
next(it)
File "", line 13, in next
raise StopIteration()
StopIteration
英文原文:http://www.pythonabc.com/iterable-and-iterator/
译者:诗书塞外