python使用迭代器注意事项

0、问题背景

看了段大牛的开源代码:

“”“
author='Kenneth Reitz',
author_email='me@kennethreitz.org',
url='https://github.com/kennethreitz/records',

”“”

def as_dict(self, ordered=False):
    """Returns the row as a dictionary, as ordered."""
    items = zip(self.keys(), self.values())

    return OrderedDict(items) if ordered else dict(items)

1、发现一个问题–代码展示不完全

当时觉得这个zip很诡异,只能用一次,后面再操作就为空。虽然知道它是迭代器,但不够彻底了解它特性。自己写了段:

	
	items = zip(['c','a',"b","1a",], [3,5,1,2])
	
	
	dict(items)
	Out[5]: {}
	
	items
	Out[6]: <zip at 0x2702fa94908>
	
	list(items)
	Out[7]: []
	
	dict(zip(['c','a',"b","1a",], [3,5,1,2]))
	Out[8]: {'c': 3, 'a': 5, 'b': 1, '1a': 2}

问题:
从上可以看出,表面层面,zip单独赋值后,再做操作就会为空;
疑问大神的那个源码不会为空么?
虽然zip里面的是self的方法。

原因猜测:
是zip里面含有__next__方法,为迭代器方法,该方法默认是会返回下一行?还有进一步的深层次的原因么?

2、第二次再验证

第二次问题再发现–对zip的操作第一次的时候是ok的,操作第二次就不行了;
经查资料,发现迭代器是一个数据流,迭代完了就没有了;

	
	item = zip(['c','a'],[1,2])
	item
	Out[12]: <zip at 0x159a702b2c8>
	dict(item)
	Out[13]: {'c': 1, 'a': 2}
	dict(item)
	Out[14]: {}
	
	###dict(zip())这种用的是zip的哪次迭代?可以看dict的源码;
	
	def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
	    """
	    dict() -> new empty dictionary
	    dict(mapping) -> new dictionary initialized from a mapping object's
	        (key, value) pairs
	    dict(iterable) -> new dictionary initialized as if via:
	        d = {}
	        for k, v in iterable:
	            d[k] = v
	    dict(**kwargs) -> new dictionary initialized with the name=value pairs
	        in the keyword argument list.  For example:  dict(one=1, two=2)
	    # (copied from class doc)
	    """
	    pass

从上面dict源码可以看出,对于迭代器,外层加dict,是相当于做了一次迭代器的循环,一一遍历定义key-value;

3、迭代器的遍历

(1)通常的迭代器迭代完了之后会终止异常:

item = zip(['c','a'],[1,2])
item
Out[7]: <zip at 0x159a7022f88>
item.__next__()
Out[8]: ('c', 1)
item.__next__()
Out[9]: ('a', 2)
item.__next__()
Traceback (most recent call last):
  File "C:\Users\ccs\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-10-06da4fbfb813>", line 1, in <module>
    item.__next__()
StopIteration

(2)对于for循环,迭代器会提前终止,不会抛出异常:

item = zip(['c','a'],[1,2])
for i in item:
   ...:     print(i)
   ...:     
('c', 1)
('a', 2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值