python中的迭代器和生成器

2019/04/10 10:10
阅读数 12

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px; padding: 10px; word-spacing: 0px; word-break: break-word; word-wrap: break-word; text-align: left; line-height: 1.75; color: #595959; font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light; letter-spacing: 2px; background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%); background-size: 20px 20px; background-position: center center;"><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">在我们学习迭代器和生成器之前的时候,我们要先搞清楚几个概念:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: #595959; list-style-type: circle;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><strong style="color: #595959; font-weight: bold;"><span>「</span>迭代协议:<span>」</span></strong> 有<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__</code>方法会前进道下一个结果,而且在一系列结果的末尾时,会引发<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">StopIteration</code>异常的对象.</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><strong style="color: #595959; font-weight: bold;"><span>「</span>可迭代对象:<span>」</span></strong> 实现了<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__iter__</code>方法的对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><strong style="color: #595959; font-weight: bold;"><span>「</span>迭代器:<span>」</span></strong> 实现了<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__iter__</code>和<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__</code>方法的对象</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><strong style="color: #595959; font-weight: bold;"><span>「</span>生成器:<span>」</span></strong> 通过生成器表达式或者yeild关键字实现的函数.</section></li></ul> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">这里不太好理解,我们借用一个图 <img src="http://wmcoding.oss-cn-hangzhou.aliyuncs.com/wmcoding/20200314/003516884.png" alt style="width: auto; max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain;"></p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">可迭代对象</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">需要注意的是可迭代对象不一定是迭代器.比如列表类型和字符串类型都是可迭代对象,但是他们都不是迭代器.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>]: L1 = [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>]<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>]: type(L1)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>]: list<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>]: L1_iter=L1.__iter__()<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>]: type(L1_iter)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>]: list_iterator<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">但是对于容器以及文件这样的可迭代对象来说的话,他们都实现了一个<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__iter__</code>方法. 这个方法可以返回一个迭代器. <img src="http://wmcoding.oss-cn-hangzhou.aliyuncs.com/wmcoding/20200314/003546850.png" alt style="width: auto; max-width: 100%; border-radius: 6px; display: block; margin: 20px auto; object-fit: contain;"></p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">迭代器中的<code>__next__</code>方法,<code>next()</code>方法和<code>for</code>语句</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">首先迭代器中都实现了<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__()</code>方法. 我们可以直接调用迭代器的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__</code>方法来得到下一个值. 比如:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span>]: L1_iter.__next__()<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">11</span>]: next(L1_iter)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">11</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span><br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">注意这里,next()方法也是去调用迭代器内置的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__</code>方法. 所以这两种操作是一样的. 但是在日常使用的时候,我们不会直接去调用next()方法来使用生成器.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">更多的操作是通过for语句来使用一个生成器.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">就下面这两段代码来看,其作用上是等效的.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">L1 = [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>]<br><br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> L1:<br> print(x, end=<span class="hljs-string" style="color: #98c379; line-height: 26px;">" "</span>)<br><br>print(<span class="hljs-string" style="color: #98c379; line-height: 26px;">"\nthe same result of those two statements!"</span>)<br><br>L1_iter = L1.__iter__()<br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">while</span> <span class="hljs-literal" style="color: #56b6c2; line-height: 26px;">True</span>:<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">try</span>:<br> x = L1_iter.__next__()<br> print(x, end=<span class="hljs-string" style="color: #98c379; line-height: 26px;">" "</span>)<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">except</span> StopIteration:<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">break</span><br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">但是实际上,使用for语句在运行速度可能会更快一点. 因为迭代器在Python中是通过C语言实现的. 而while的方式则是以Python虚拟机运行Python字节码的方式来执行的.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">毕竟...你大爷永远是你大爷. C语言永远是你大爷...</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">列表解析式</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">列表解析式或者又叫列表生成式,这个东西就比较简单了. 举个简单的例子,比如我们要定义一个1-9的列表. 我们可以写<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">L=[1,2,3,4,5,6,78,9]</code> 同样我们也可以写<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">L=[x for x in range(10)]</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">再举一个简单的例子,我们现在已经有一个列表<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">L2=[1,2,3,4,5]</code> 我们要得到每个数的平方的列表. 那么我们有两种做法:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">L2 = [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>]<br><br><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;"># statement1</span><br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(len(L2)):<br> L2[i] = L2[i]*L2[i]<br><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">#statement2</span><br>L3 = [x*x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> L2]<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">显然从代码简洁渡上来说 第二种写法更胜一筹. 而且它的运算速度相对来说会更快一点(往往速度会快一倍.P.S.书上的原话,我没有验证...). 因为列表解析式式通过生成器来构造的,他们的迭代是python解释器内部以C语言的速度来运行的. 特别是对于一些较大的数据集合,列表解析式的性能优点更加突出.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">列表解析式还有一些高端的玩法. 比如可以与if语句配合使用:</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">L4 = [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">6</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">7</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">8</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">9</span>]<br><br>L5 = [x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> L4 <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> x % <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span> == <span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>]<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">还可以使用for语句嵌套;</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">L6=[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>]<br>L7=[<span class="hljs-string" style="color: #98c379; line-height: 26px;">'a'</span>,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'b'</span>,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'c'</span>,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'d'</span>,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'e'</span>]<br><br>L8=[str(x)+y <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> L6 <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> y <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> L7]<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">或者可以写的更长</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">L9=[(x,y) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> x % <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span> ==<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> y <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">if</span> y %<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span> ==<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>]<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">一个更复杂的例子</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">M = [<br> [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>],<br> [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">6</span>],<br> [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">7</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">8</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">9</span>]<br>]<br>print(M[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>][<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>])<br>print(M[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>])<br>print([row[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>] <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> row <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> M])<br>print([M[row][<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>] <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> row <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> (<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>)])<br>print([M[i][i] <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(len(M))])<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">同样的,我们可以通过for语句来实现上述的功能. 但是列表解析式想对而言会更加简洁.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">另外map函数比等效的for循环要更快,而列表解析式往往会比map调用还要快一点.</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">python3中新的可迭代对象</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">python3相比如python2.x来说,它更强调迭代. 除了文件,字典这样的内置类型相关的迭代外. 字典方法keys,values都在python3中返回可迭代对象. 就像map,range,zip方法一样. 它返回的并不是一个列表. 虽然从速度和内存占用上更有优势,但是有时候我们不得不使用list()方法使其一次性计算所有的结果.</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">range迭代器</span></h3> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">12</span>]: R=range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span>)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">13</span>]: R<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">13</span>]: range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>, <span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span>)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">14</span>]: I = iter(R)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">15</span>]: next(I)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">15</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">16</span>]: R[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>]<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">16</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">17</span>]: len(R)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">17</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">18</span>]: next(I)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">18</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span><br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">range的话,仅支持迭代,len()和索引. 不支持其他的序列操作. 所以如果需要更多的列表工具的话,使用list()...</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">map,zip和filter迭代器</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">和range类似, map,zip和filter在python3.0中也转变成了迭代器以节约内存空间. 但是它们和range又不一样.(确切来说是range和它们不一样) 它们不能在它们的结果上拥有在那些结果中保持不同位置的多个迭代器.(第四版书上原话,看看这叫人话吗...)</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">翻译一下就是,map,zip和filter返回的都是正经迭代器,不支持len()和索引. 以map为例做个对比.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">20</span>]: map_abs = map(abs,[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">-3</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>])<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">21</span>]: M1 = iter(map_abs)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">22</span>]: M2=iter(map_abs)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">23</span>]: next(M1)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">23</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">24</span>]: next(M2)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">24</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span><br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">而range不是正经的迭代器. 它支持在其结果上创建多个活跃的迭代器.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">25</span>]: R=range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">10</span>)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">26</span>]: r1 = iter(R)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">27</span>]: r2=iter(R)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">28</span>]: next(r1)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">28</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">29</span>]: next(r2)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">29</span>]: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span><br></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">字典中的迭代器</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">同样的,python3中字典的keys,values和items方法返回的都是可迭代对象.而非列表.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">30</span>]: D = dict(a=<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,b=<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,c=<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">31</span>]: D<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">31</span>]: {<span class="hljs-string" style="color: #98c379; line-height: 26px;">'a'</span>: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'b'</span>: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'c'</span>: <span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>}<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">32</span>]: K = D.keys()<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">33</span>]: K<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">33</span>]: dict_keys([<span class="hljs-string" style="color: #98c379; line-height: 26px;">'a'</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'b'</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'c'</span>])<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">34</span>]: next(K)<br>---------------------------------------------------------------------------<br>TypeError Traceback (most recent call last)<br>&lt;ipython-input<span class="hljs-number" style="color: #d19a66; line-height: 26px;">-34</span><span class="hljs-number" style="color: #d19a66; line-height: 26px;">-02</span>c2ef8731e9&gt; <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> &lt;module&gt;<br>----&gt; <span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span> next(K)<br><br>TypeError: <span class="hljs-string" style="color: #98c379; line-height: 26px;">'dict_keys'</span> object <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">is</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">not</span> an iterator<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">35</span>]: i = iter(K)<br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">36</span>]: next(i)<br>Out[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">36</span>]: <span class="hljs-string" style="color: #98c379; line-height: 26px;">'a'</span><br><br>In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">37</span>]: <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> k <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> D.keys(): print(k,end=<span class="hljs-string" style="color: #98c379; line-height: 26px;">' '</span>)<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">同样的,我们可以利用list()函数来显式的把他们变成列表. 另外,python3中的字典仍然有自己的迭代器. 它返回连续的见. 因此在遍历的时候,无需显式的调用keys().</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">In [<span class="hljs-number" style="color: #d19a66; line-height: 26px;">38</span>]: <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> key <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> D: print(key,end=<span class="hljs-string" style="color: #98c379; line-height: 26px;">' '</span>)<br>a b c<br></code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">生成器</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">生成器可以说是迭代器的一个子集. 有两种创建方法:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: #595959; list-style-type: circle;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;">生成器函数: 编写常规的以def为关键字的函数,使用yield关键字返回结果. 在每个结果之间挂起和继续他们的状态.</section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;">生成器表达式: 类似前面所说的列表解析式.</section></li></ul> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">生成器函数关键字 yeild</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>状态挂起<span>」</span></strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">和返回一个值并且退出的常规函数不同,生成器函数自动在生成值得时刻挂起并继续函数的执行. 它在挂起时会保存包括整个本地作用域在内的所有状态. 在恢复执行时,本地变量信息依旧可用.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">生成器函数使用yeild语句来挂起函数并想调用者发送回一个值.之后挂起自己. 在恢复执行的时候,生成器函数会从它离开的地方继续执行.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>生成器函数的应用<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">gensquares</span><span class="hljs-params" style="line-height: 26px;">(num)</span>:</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(num):<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">yield</span> i**<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span><br><br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> gensquares(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>):<br> print(i)<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">同样的,生成器其实也是实现了迭代器协议. 提供了内置的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: #595959;">__next__</code>方法.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">上面这个例子如果我们要改写为普通函数的话,可以写成如下的样子.</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">buildsquares</span><span class="hljs-params" style="line-height: 26px;">(num)</span>:</span><br> res = []<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(num):<br> res.append(i**<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>)<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> res<br><br><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> i <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> buildsquares(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>):<br> print(i)<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">看上去实现的功能都是一样的. 但是区别在于 生成器的方式产生的是一个惰性计算序列. 在调用时才进行计算得出下一个值. 而第二种常规函数的方式,是先计算得出所有结果返回一个列表. 从内存占用的角度来说,生成器函数的方式更优一点.</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">生成器表达式</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">与列表解析式差不多. 生成器表达式用来构造一些逻辑相对简单的生成器. 比如</p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;">g = (x**<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> x <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> range(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>))<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;">在使用时可以通过next()函数或者for循环进行调用.</p> <h2 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; font-weight: bold; color: black; font-size: 24px; text-align: left; margin: 20px 10px 0px 0px;"><span style="font-size: 18px; font-weight: bold; display: inline-block; padding-left: 10px; border-left: 5px solid #DEC6FB; color: #595959;">实战:改写map和zip函数</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">改写map函数</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>一年级版本:<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">mymap</span><span class="hljs-params" style="line-height: 26px;">(func,*seqs)</span>:</span><br> res=[]<br> print(list(zip(*seqs)))<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> args <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> zip(*seqs):<br> res.append(func(*args))<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> res<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>二年级版本:<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">mymap</span><span class="hljs-params" style="line-height: 26px;">(func,*seqs)</span>:</span>&nbsp;&nbsp;&nbsp; <br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> [func(*args) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> args <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> zip(*seqs)]<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>三年级版本:<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">mymap</span><span class="hljs-params" style="line-height: 26px;">(func,*seqs)</span>:</span><br> res=[]<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> args <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> zip(*seqs):<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">yield</span> func(*args)<br><br><br>print(list(mymap(abs,[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">-1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">-2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>])))<br>print(list(mymap(pow,[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>],[<span class="hljs-number" style="color: #d19a66; line-height: 26px;">2</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">3</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">4</span>,<span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>])))<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>小学毕业班版本<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">mymap</span><span class="hljs-params" style="line-height: 26px;">(func,*seqs)</span>:</span><br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> (func(*args) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> args <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> zip(*seqs))<br></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 40px; margin-bottom: 20px; color: black; font-size: 16px; font-weight: bold; text-align: center;"><span style="border-bottom: 2px solid #DEC6FB; color: #595959;">改写zip函数</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>一年级版本<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">myzip</span><span class="hljs-params" style="line-height: 26px;">(*seqs)</span>:</span><br> seqs = [list(S) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> S <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> seqs]<br> print(seqs)<br> res = []<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">while</span> all(seqs):<br> res.append(tuple(S.pop(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> S <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> seqs))<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">return</span> res<br><br><br>print(myzip(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'abc'</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'xyz'</span>))<br></code></pre> <blockquote data-tool="mdnice编辑器" style="display: block; font-size: 0.9em; overflow: auto; overflow-scrolling: touch; padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 10px; margin-bottom: 20px; margin-top: 20px; text-size-adjust: 100%; line-height: 1.55em; font-weight: 400; border-radius: 6px; color: #595959; font-style: normal; text-align: left; box-sizing: inherit; border-left: none; border: 1px solid #DEC6FB; background: #F6EEFF;"><span style="color: #DEC6FB; font-size: 34px; line-height: 1; font-weight: 700;">❝</span> <p style="padding-top: 8px; padding-bottom: 8px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px; margin: 0px; line-height: 26px; color: #595959;">知识点: all()函数和any()函数. <a href="https://docs.python.org/zh-cn/3.7/library/functions.html#all" style="text-decoration: none; word-wrap: break-word; color: #664D9D; font-weight: normal; border-bottom: 1px solid #664D9D;">all()函数</a>,如果可迭代对象中的所有元素都为True或者可迭代对象为None. 则返回True. <a href="https://docs.python.org/zh-cn/3.7/library/functions.html#any" style="text-decoration: none; word-wrap: break-word; color: #664D9D; font-weight: normal; border-bottom: 1px solid #664D9D;">any()函数</a>,可迭代对象中的任一元素为True则返回True.,如果迭代器为空,则返回False.</p> <span style="float: right; color: #DEC6FB;">❞</span></blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 26px; color: #595959; margin: 10px 0px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px;"><strong style="color: #595959; font-weight: bold;"><span>「</span>二年级版本<span>」</span></strong></p> <pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px;"><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; background: #282c34; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; border-radius: 0px; font-size: 12px; -webkit-overflow-scrolling: touch;"><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">def</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">myzip</span><span class="hljs-params" style="line-height: 26px;">(*seqs)</span>:</span><br> seqs = [list(S) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> S <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> seqs]<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">while</span> all(seqs):<br> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">yield</span> tuple(S.pop(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>) <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span> S <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">in</span> seqs)<br><br>print(list(myzip(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'abc'</span>, <span class="hljs-string" style="color: #98c379; line-height: 26px;">'xyz'</span>)))<br></code></pre> <blockquote data-tool="mdnice编辑器" style="display: block; font-size: 0.9em; overflow: auto; overflow-scrolling: touch; padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 10px; margin-bottom: 20px; margin-top: 20px; text-size-adjust: 100%; line-height: 1.55em; font-weight: 400; border-radius: 6px; color: #595959; font-style: normal; text-align: left; box-sizing: inherit; border-left: none; border: 1px solid #DEC6FB; background: #F6EEFF;"><span style="color: #DEC6FB; font-size: 34px; line-height: 1; font-weight: 700;">❝</span> <p style="padding-top: 8px; padding-bottom: 8px; letter-spacing: 2px; font-size: 14px; word-spacing: 2px; margin: 0px; line-height: 26px; color: #595959;">参考资料:</p> <ul style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; font-size: 15px; color: #595959; list-style-type: circle;"> <li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><a href="https://nvie.com/posts/iterators-vs-generators/" style="text-decoration: none; word-wrap: break-word; color: #664D9D; font-weight: normal; border-bottom: 1px solid #664D9D;">Iterables vs. Iterators vs. Generators</a></section></li><li><section style="margin-top: 5px; margin-bottom: 5px; line-height: 26px; text-align: left; font-size: 14px; font-weight: normal; color: #595959;"><a href="https://learning-python.com/" style="text-decoration: none; word-wrap: break-word; color: #664D9D; font-weight: normal; border-bottom: 1px solid #664D9D;">Python学习手册(第五版)</a></section></li></ul> <span style="float: right; color: #DEC6FB;">❞</span></blockquote> </section>

原文出处:https://www.cnblogs.com/thecatcher/p/12490184.html

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部