test_list = [1, 2, 3]
test_dump = {"name": "zhangsan", "age": "12"}
for i in test_list:
print(i)
print(type(i))
for key in test_dump:
print(key)
print(test_dump[key])
print(type(key))
结果
1
2
3
name
zhangsan
age
12
先说概念
Iterable 可迭代对象,for loop的 in 后面必须是一个Iterable 数据的保存者,可以没有状态,他不必知道iterator数到了哪里,但是必须有能力产生一个iterator
一个Iterable,要么有__iter__这个method,要么就需要是一个sequence(顺序排列,队列),有__getitem__这个method,这两个都是为了保证可以返 回一个iterator。
iterator 迭代器,表示数据流的对象,iterator必须是有状态的,但是并不需要实现一个Iterable,一个iterator必须要有__next__这个方法,这个method保证他在被 next作用的时候,可以返回下一个Iterable里的值,也就是一个新的iterator
for loop的时候会先对Iterable进行一个iter()操作,然后再根据iterator进行操作,加下来我们来理解一下上面这些概念的意思
class NodeIter:
def __init__(self, node):
self.curr_node = node
def __next__(self):
if self.curr_node is None:
# 如果数据已经到头了,就需要抛出错误
raise StopIteration
# 没有到头的话,就返回这个node,并且把下一个值存储
node, self.curr_node = self.curr_node, self.curr_node.next
return node
class Node:
def __init__(self, name):
self.name = name
self.next = None
def __iter__(self):
# Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
return NodeIter(self)
node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3
for node in node1:
# 等于for node in iter(node1),向Iterable要了一个iterator
print(node.name)
结果
Node1
Node2
Node3
但是呢官方推荐这个iterator除了有__next__函数之外,还需要有__iter__函数,是为了让每一个iterator也是一个Iterable,就是让每一个迭代器也是可迭代的
class NodeIter:
def __init__(self, node):
self.curr_node = node
def __next__(self):
if self.curr_node is None:
# 如果数据已经到头了,就需要抛出错误
raise StopIteration
# 没有到头的话,就返回这个node,并且把下一个值存储
node, self.curr_node = self.curr_node, self.curr_node.next
return node
class Node:
def __init__(self, name):
self.name = name
self.next = None
def __iter__(self):
# Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
return NodeIter(self)
node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3
# 先求了一个iterator出来
it = iter(node1)
# 将iterator的第一个值取出来了
first = next(it)
# 再来迭代it这个iterator
for node in it:
# 等于for node in iter(node1)
print(node.name)
报错
TypeError: 'NodeIter' object is not iterable
看起来是不是很难受
class NodeIter:
def __init__(self, node):
self.curr_node = node
def __next__(self):
if self.curr_node is None:
# 如果数据已经到头了,就需要抛出错误
raise StopIteration
# 没有到头的话,就返回这个node,并且把下一个值存储
node, self.curr_node = self.curr_node, self.curr_node.next
return node
# 解决办法很简单,就是在iterator里也实现一个__iter__方法,返回他自己就可以了
def __iter__(self):
return self
class Node:
def __init__(self, name):
self.name = name
self.next = None
def __iter__(self):
# Node是一个Iterable,但是他的__iter__方法,返回了一个iterator
return NodeIter(self)
node1 = Node("Node1")
node2 = Node("Node2")
node3 = Node("Node3")
node1.next = node2
node2.next = node3
# 先求了一个iterator出来
it = iter(node1)
# 将iterator的第一个值取出来了
first = next(it)
# 再来迭代it这个iterator
for node in it:
# 等于for node in iter(node1)
print(node.name)
结果
Node2
Node3