matplotlib文档中的颜色循环器示例很神秘(python)
有没有人能给我解释一下这个例子是如何工作的,摘自持久循环一节下面的部分 本质上,它们创建颜色循环器,我不确定它们是工厂函数、迭代器还是普通函数或对象。你可以用有限的matplotlib文档中的颜色循环器示例很神秘(python),python,matplotlib,colors,iterator,Python,Matplotlib,Colors,Iterator,有没有人能给我解释一下这个例子是如何工作的,摘自持久循环一节下面的部分 本质上,它们创建颜色循环器,我不确定它们是工厂函数、迭代器还是普通函数或对象。你可以用有限的iter(my\u cycler)和my\u cycler()用itertools.cycle生成器把它们做成一个生成器。我不明白这是怎么回事 所以我的问题是:为什么你能做iter(my\u cycler),它给出有限的东西,为什么你能做my\u cycler(),它给出相同的东西,但却是无限的(它循环) >>从Cycle导入Cycl
iter(my\u cycler)
和my\u cycler()
用itertools.cycle生成器把它们做成一个生成器。我不明白这是怎么回事
所以我的问题是:为什么你能做iter(my\u cycler)
,它给出有限的东西,为什么你能做my\u cycler()
,它给出相同的东西,但却是无限的(它循环)
>>从Cycle导入Cycle
>>>cyl=循环器(颜色=['r','g','b'])
>>>类型(cyl)
骑自行车的,骑自行车的
>>>进口自行车
>>>骑自行车的,骑自行车的__
(Cycle.Cycle,对象)
>>>类型(cyl())
itertools.cycle
>>类型(iter(cyl))
发电机
当我打字时:
>>下一步(气缸)
TypeError:“Cycle”对象不是迭代器
但不知怎的,这是可行的:
>>> for s in cyl:
... print(s)
{'color': 'r'}
{'color': 'g'}
{'color': 'b'}
另一个问题是defaultdict的奇怪应用style=defaultdict(lambda:next(finite\u cy\u iter))
。我想我大致理解了它,但我想确定:每当一个键不在dict中时,就会调用(lambda:next(finite_cy_iter))()
或其他什么。根据defaultdicts上的文档,您必须给它一个函数,在本例中,function=(lambda:next(finite_cy_iter))
。所以我猜每次调用dict函数时,都会调用一个键,实际上这是一个伪装的迭代器,它会给你循环器中的下一个dict,然后它会被存储为该键的值
以下是matplotlib文档中的部分:
持续周期
通过字典查找将给定标签与样式关联并动态生成该映射非常有用。这可以使用defaultdict轻松完成
[40]中的from cycler将cycler导入为cy
In[41]:从集合导入defaultdict
在[42]中:cyl=cy('c','rgb')+cy('lw',范围(1,4))
获取一组有限的样式
[43]中的finite\u cy\u iter=iter(cyl)
在[44]中:dd_finite=defaultdict(lambda:next(finite_cy_iter))
或重复
在[45]中:loop\u cy\u iter=cyl()
在[46]中:dd_loop=defaultdict(lambda:next(loop_cy_iter))
这在打印既有分类又有标签的复杂数据时很有用
finite_cy_iter=iter(cyl)
styles=defaultdict(lambda:next(有限周期))
对于数据集中的组、标签和数据:
ax.plot(数据,标签=标签,**样式[组])
这将导致同一组的每个数据以相同的样式绘制。关于问题的第一部分
所以我的问题是:为什么你能做iter(my\u cycler)
,它给出有限的东西,为什么你能做my\u cycler()
,它给出相同的东西,但却是无限的(它循环)
cycler
类的行为是这样的,因为它的定义是这样的,看看这个简单的例子,看看我的意思
In [13]: class callable_list(list):
...: def __call__(self):
...: from itertools import cycle
...: return cycle(self)
In [14]: l = callable_list((1,2))
In [15]: l
Out[15]: [1, 2]
In [16]: it_l = iter(l) ; cy_l = l()
In [17]: for _ in range(3): print(next(it_l))
1
2
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-17-e4324d8268a6> in <module>
----> 1 for _ in range(3): print(next(it_l))
StopIteration:
In [18]: for _ in range(3): print(next(cy_l))
1
2
1
从单循环器开始,首先[1:2]
,对我来说,它返回一个值
In [2]: c[1:2]
Out[2]: cycler('c', ['g'])
然后是[1:1]
,同样是一个单一值,即空循环器
In [3]: c[1:1] # empty cycler
Out[3]: cycler('c', [])
请注意,这类似于对列表进行切片,在任何情况下,表达式的值都是单个对象、列表,可能是空列表……没有什么新内容
最后,让我们看看在切片外部产品时会发生什么,但首先让我们看看内部是什么
In [5]: for i, d in enumerate(cw): print(i, d)
0 {'c': 'r', 'lw': 1}
1 {'c': 'r', 'lw': 2}
2 {'c': 'r', 'lw': 3}
3 {'c': 'r', 'lw': 4}
4 {'c': 'g', 'lw': 1}
5 {'c': 'g', 'lw': 2}
6 {'c': 'g', 'lw': 3}
7 {'c': 'g', 'lw': 4}
8 {'c': 'b', 'lw': 1}
9 {'c': 'b', 'lw': 2}
10 {'c': 'b', 'lw': 3}
11 {'c': 'b', 'lw': 4}
现在我们通过切片来解决它
In [6]: cw[3:9]
Out[6]: (cycler('c', ['r', 'g', 'g', 'g', 'g', 'b']) + cycler('lw', [4, 1, 2, 3, 4, 1]))
结果是一个单循环器,即两个循环器的内积,在展开到上述枚举打印输出的位置3÷8时对应
最后,让我们使用[3:3]
来解决cw
,也就是说,一个空片段(扰流板,不会有什么好事发生!)
[7]中的cw[3:3]
---------------------------------------------------------------------------
StopIteration回溯(最后一次调用)
在里面
---->1 cw[3:3]
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in\uuuuu getitem\uuuuuu(self,key)
219 trans=通过按键进行的自我测试()
220返回减少(添加,(_循环器(k,v[键])
-->221表示k,v在六个元素中。iteritems(trans)))
222其他:
223 raise VALUE ERROR(“只能将切片与循环器一起使用。”\uuuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuu”)
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in\uuuu添加(self,other)
241 raise VALUE ERROR(“只能添加等长循环,”
242“非{0}和{1}”。格式(len(self),len(other)))
-->243返回循环器(自身、其他、拉链)
244
245 def_uuumul_uuu(自身、其他):
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py在uuuu init_uuu中(self,left,right,op)
116 """
117如果存在(左侧,循环器):
-->118 self.\u left=循环器(左。\左,左。\右,左。\ op)
119如果“左”不是“无”:
120#需要复制字典,否则这将是一个残余
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py在uuuu init_uuu中(self,left,right,op)
133自右=无
134
-->135 self.\u键=\u进程\u键(self.\u左,self.\u右)
136自我。_op=op
137
进程键中的~/lib/miniconda3/lib/python3.7/site-packages/cycler.py(左、右)
66两个循环器组合中的键
67 """
--->68 l_peek=下一个(iter(左))如果左不是其他{}
69 r_peek=next(iter(right))如果right不是None-other{}
70 l_key=set(l_peek.keys())
停止迭代:
在[8]中:
以我谦卑的态度
In [6]: cw[3:9]
Out[6]: (cycler('c', ['r', 'g', 'g', 'g', 'g', 'b']) + cycler('lw', [4, 1, 2, 3, 4, 1]))
In [7]: cw[3:3]
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-7-1bf3cb52c570> in <module>
----> 1 cw[3:3]
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in __getitem__(self, key)
219 trans = self.by_key()
220 return reduce(add, (_cycler(k, v[key])
--> 221 for k, v in six.iteritems(trans)))
222 else:
223 raise ValueError("Can only use slices with Cycler.__getitem__")
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in __add__(self, other)
241 raise ValueError("Can only add equal length cycles, "
242 "not {0} and {1}".format(len(self), len(other)))
--> 243 return Cycler(self, other, zip)
244
245 def __mul__(self, other):
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in __init__(self, left, right, op)
116 """
117 if isinstance(left, Cycler):
--> 118 self._left = Cycler(left._left, left._right, left._op)
119 elif left is not None:
120 # Need to copy the dictionary or else that will be a residual
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in __init__(self, left, right, op)
133 self._right = None
134
--> 135 self._keys = _process_keys(self._left, self._right)
136 self._op = op
137
~/lib/miniconda3/lib/python3.7/site-packages/cycler.py in _process_keys(left, right)
66 The keys in the composition of the two cyclers
67 """
---> 68 l_peek = next(iter(left)) if left is not None else {}
69 r_peek = next(iter(right)) if right is not None else {}
70 l_key = set(l_peek.keys())
StopIteration:
In [8]: