-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathIterables.html
More file actions
480 lines (347 loc) · 35.7 KB
/
Iterables.html
File metadata and controls
480 lines (347 loc) · 35.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="zh-CN" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="zh-CN" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta content="Topic: the basics of iterables in python, Difficulty: Medium, Category: Section" name="description" />
<meta content="iterables, max, min, sum, all, any, itertools, enumerate, unpack" name="keywords" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可迭代物 — Python Like You Mean It</title>
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="https://www.googletagmanager.com/gtag/js?id=UA-115029372-1"></script>
<script src="../_static/gtag.js"></script>
<script src="../_static/translations.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["$", "$"], ["\\(", "\\)"]], "processEscapes": true, "ignoreClass": "document", "processClass": "math|output_area"}})</script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/my_theme.css" type="text/css" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="next" title="生成器和理解表达式" href="Generators_and_Comprehensions.html" />
<link rel="prev" title="For循环和While循环" href="ForLoops.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> Python Like You Mean It
</a>
<div class="version">
1.4
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<p class="caption"><span class="caption-text">目录:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../intro.html">Python Like You Mean It</a></li>
<li class="toctree-l1"><a class="reference internal" href="../module_1.html">模组1:Python入门</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../module_2.html">模组2:Python基础</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Basic_Objects.html">基本对象类型</a></li>
<li class="toctree-l2"><a class="reference internal" href="SequenceTypes.html">序列类型</a></li>
<li class="toctree-l2"><a class="reference internal" href="Variables_and_Assignment.html">变量和赋值</a></li>
<li class="toctree-l2"><a class="reference internal" href="Introduction.html">控制流简介</a></li>
<li class="toctree-l2"><a class="reference internal" href="ConditionalStatements.html">条件语</a></li>
<li class="toctree-l2"><a class="reference internal" href="ForLoops.html">For循环和While循环</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">可迭代物</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#操作可迭代物的函数">操作可迭代物的函数</a></li>
<li class="toctree-l3"><a class="reference internal" href="#操作可迭代物的技巧">操作可迭代物的技巧</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#“解包”可迭代物">“解包”可迭代物</a></li>
<li class="toctree-l4"><a class="reference internal" href="#枚举可迭代物">枚举可迭代物</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#官方说明文档链接">官方说明文档链接</a></li>
<li class="toctree-l3"><a class="reference internal" href="#阅读理解答案">阅读理解答案</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="Generators_and_Comprehensions.html">生成器和理解表达式</a></li>
<li class="toctree-l2"><a class="reference internal" href="Itertools.html">Python的“Itertools”</a></li>
<li class="toctree-l2"><a class="reference internal" href="Functions.html">函数基础</a></li>
<li class="toctree-l2"><a class="reference internal" href="Scope.html">作用域</a></li>
<li class="toctree-l2"><a class="reference internal" href="DataStructures.html">数据结构(第一部分):简介</a></li>
<li class="toctree-l2"><a class="reference internal" href="DataStructures_II_Dictionaries.html">数据结构(第二部分):词典</a></li>
<li class="toctree-l2"><a class="reference internal" href="DataStructures_III_Sets_and_More.html">数据结构(第三部分):集和集合模组</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../module_2_problems.html">模组2:题目</a></li>
<li class="toctree-l1"><a class="reference internal" href="../module_3.html">模组3:NumPy基础</a></li>
<li class="toctree-l1"><a class="reference internal" href="../module_3_problems.html">模组3:题目</a></li>
<li class="toctree-l1"><a class="reference internal" href="../module_4.html">模组4:面向对象编程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../module_5.html">模组5:琐碎话题</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Python Like You Mean It</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html">Docs</a> »</li>
<li><a href="../module_2.html">模组2:Python基础</a> »</li>
<li>可迭代物</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/Module2_EssentialsOfPython/Iterables.md.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<style>
/* CSS overrides for sphinx_rtd_theme */
/* 24px margin */
.nbinput.nblast.container,
.nboutput.nblast.container {
margin-bottom: 19px; /* padding has already 5px */
}
/* ... except between code cells! */
.nblast.container + .nbinput.container {
margin-top: -19px;
}
.admonition > p:before {
margin-right: 4px; /* make room for the exclamation icon */
}
/* Fix math alignment, see https://github.com/rtfd/sphinx_rtd_theme/pull/686 */
.math {
text-align: unset;
}
</style>
<div class="section" id="可迭代物">
<h1>可迭代物<a class="headerlink" href="#可迭代物" title="永久链接至标题">¶</a></h1>
<p>我们之前在讨论for循环的时候介绍了<em>可迭代物</em>(iterable)——也就是任何你可以“迭代”(如for循环)的对象。</p>
<div class="admonition note">
<p class="admonition-title fa fa-exclamation-circle"><strong>定义</strong>:</p>
<p><strong>可迭代物</strong>泛指任何支持一次返回一个成员的Python对象。这使得它可以用for循环迭代。</p>
</div>
<p>常见的可迭代物包括列表,元组,和字符串——任何你可以用for循环迭代的序列(sequence)。我们也将遇到一些并非序列的集合,如词典(dictionary)和集(set);这些也是可迭代物。Python也提供在每轮迭代时“生成”(generate)一个成员的可迭代物——也就是说它甚至不需要同时在内存中存储所有的成员。我们会在后文花一整节来讨论生成器(generator)——一种特殊的迭代器——因为它们会帮助我们编写高效率的代码。</p>
<p>本节将会讨论如何在你的代码中使用可迭代物。</p>
<div class="admonition warning">
<p class="admonition-title fa fa-exclamation-circle"><strong>注</strong>:</p>
<p>在“幕后”,可迭代物是任何提供 <code class="docutils literal notranslate"><span class="pre">__iter__()</span></code> 方法(method)或实现了 <code class="docutils literal notranslate"><span class="pre">Sequence</span></code> 语义的 <code class="docutils literal notranslate"><span class="pre">__getitem__()</span></code> 方法的Python对象。在你阅读面向对象模组时,这些细节将会更加显著。</p>
</div>
<div class="section" id="操作可迭代物的函数">
<h2>操作可迭代物的函数<a class="headerlink" href="#操作可迭代物的函数" title="永久链接至标题">¶</a></h2>
<p>以下是一些有用的操作可迭代物的函数:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">list</span></code>, <code class="docutils literal notranslate"><span class="pre">tuple</span></code>, <code class="docutils literal notranslate"><span class="pre">dict</span></code>, <code class="docutils literal notranslate"><span class="pre">set</span></code>:利用可迭代物的成员来分别创建列表,元组,<a class="reference external" href="https://cn.pythonlikeyoumeanit.com/Module2_EssentialsOfPython/DataStructures_II_Dictionaries.html">词典</a>,或<a class="reference external" href="https://cn.pythonlikeyoumeanit.com/Module2_EssentialsOfPython/DataStructures_III_Sets_and_More.html#集数据结构">集</a>。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sum</span></code>:求可迭代物内容的和。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">sorted</span></code>:返回成员为可迭代物成员顺序排列版本的列表。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">any</span></code>:迭代可迭代物。如果可迭代物中<em>任何</em>(any)一个成员满足 <code class="docutils literal notranslate"><span class="pre">bool(item)</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>,立刻返回 <code class="docutils literal notranslate"><span class="pre">True</span></code> 并终止迭代。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">all</span></code>:只有在可迭代物中<em>所有</em>(all)成员都满足 <code class="docutils literal notranslate"><span class="pre">bool(item)</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code> 时返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">max</span></code>:返回可迭代物中的最大值。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">min</span></code>:返回可迭代物中的最小值。</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 操作可迭代物内置函数的例子</span>
<span class="o">>>></span> <span class="nb">list</span><span class="p">(</span><span class="s2">"I am a cow"</span><span class="p">)</span>
<span class="p">[</span><span class="s1">'I'</span><span class="p">,</span> <span class="s1">' '</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'m'</span><span class="p">,</span> <span class="s1">' '</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">' '</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">,</span> <span class="s1">'o'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">]</span>
<span class="o">>>></span> <span class="nb">sum</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="mi">6</span>
<span class="o">>>></span> <span class="nb">sorted</span><span class="p">(</span><span class="s2">"gheliabciou"</span><span class="p">)</span>
<span class="p">[</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">,</span> <span class="s1">'e'</span><span class="p">,</span> <span class="s1">'g'</span><span class="p">,</span> <span class="s1">'h'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">,</span> <span class="s1">'l'</span><span class="p">,</span> <span class="s1">'o'</span><span class="p">,</span> <span class="s1">'u'</span><span class="p">]</span>
<span class="c1"># 以下所有物件都导致 `bool(item)` 为 `False`</span>
<span class="o">>>></span> <span class="nb">any</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">[],</span> <span class="mi">0</span><span class="p">))</span>
<span class="kc">False</span>
<span class="c1"># 以下所有物件都导致 `bool(item)` 为 `True`</span>
<span class="o">>>></span> <span class="nb">all</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">"hi"</span><span class="p">])</span>
<span class="kc">True</span>
<span class="o">>>></span> <span class="nb">max</span><span class="p">((</span><span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
<span class="mi">9</span>
<span class="o">>>></span> <span class="nb">min</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
<span class="s1">'e'</span>
</pre></div>
</div>
</div>
<div class="section" id="操作可迭代物的技巧">
<h2>操作可迭代物的技巧<a class="headerlink" href="#操作可迭代物的技巧" title="永久链接至标题">¶</a></h2>
<p>Python提供了一些用来操作可迭代物的一些语法上”技巧“:”解包“(unpack)和“枚举”(enumerate)。虽然这些功能一开始看起来像奇技淫巧,但是它们会帮助我们编写干净易读的代码和正确易懂的算法,因此我们会花一些时间去讨论它们。同时,这些技巧也会帮助我们使用其它棒棒的Python功能,如理解语句(comprehension statement)。我们会在后文进行讨论。</p>
<div class="section" id="“解包”可迭代物">
<h3>“解包”可迭代物<a class="headerlink" href="#“解包”可迭代物" title="永久链接至标题">¶</a></h3>
<p>假设你的列表中存储了三个值,且你想要将每个值赋值给一个单独的变量。利用前文的知识点,你很可能会编写以下的代码:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 将列表内容赋值给变量的简单脚本</span>
<span class="o">>>></span> <span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">x</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">y</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">z</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</pre></div>
</div>
<p>Python提供一个极其有用的功能,叫做<strong>可迭代物解包</strong>(iterable unpacking)。它允许我们编写以下优雅,简单的代码:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 使用可迭代物解包来赋值多个变量</span>
<span class="o">>>></span> <span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">my_list</span>
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="mi">7</span> <span class="mi">9</span> <span class="mi">11</span>
</pre></div>
</div>
<p>也就是说,Python直译器会“注意”赋值符左边的多个变量并以此“解包”右边的可迭代物(在此例中为一个列表)。虽然在本例中这个功能看起来没那么关键,但实际上它是一个<em>极其</em>有用的提升代码可读性的功能。</p>
<p>在for循环成员为可迭代物的可迭代物时,可迭代物解包功能极其有用。比如说,假设我们有一列表的元组,每个元组包含一对名字和成绩:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">grades</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">"Ashley"</span><span class="p">,</span> <span class="mi">93</span><span class="p">),</span> <span class="p">(</span><span class="s2">"Brad"</span><span class="p">,</span> <span class="mi">95</span><span class="p">),</span> <span class="p">(</span><span class="s2">"Cassie"</span><span class="p">,</span> <span class="mi">84</span><span class="p">)]</span>
</pre></div>
</div>
<p>根据上一节所述,如果我们循环此列表,那么每一轮迭代变量都会被赋值为其中的元组:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">grades</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
</pre></div>
</div>
<p>会打印:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="s1">'Ashley'</span><span class="p">,</span> <span class="mi">93</span><span class="p">)</span>
<span class="p">(</span><span class="s1">'Brad'</span><span class="p">,</span> <span class="mi">95</span><span class="p">)</span>
<span class="p">(</span><span class="s1">'Cassie'</span><span class="p">,</span> <span class="mi">84</span><span class="p">)</span>
</pre></div>
</div>
<p>我们很有可能会想要单独使用学生的名字和成绩(比如说,使用学生名字来访问其成绩记录并添加对应的成绩);所以说,我们需要索引 <code class="docutils literal notranslate"><span class="pre">entry</span></code> 两次来获得两个不同的变量。但是,因为for循环每一轮的赋值步骤真的其实就是 <code class="docutils literal notranslate"><span class="pre">entry</span> <span class="pre">=</span> <span class="pre">("Ashley",</span> <span class="pre">93)</span></code>,我们可以使用可迭代物解包!也就是说,我们可以用 <code class="docutils literal notranslate"><span class="pre">name,</span> <span class="pre">grade</span></code> 来代替 <code class="docutils literal notranslate"><span class="pre">entry</span></code>。Python会为其中每个变量进行解包。</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 本for循环的第一次迭代会将赋值解包:name, grade = ("Ashley", 93)</span>
<span class="c1"># 然后第二次迭代:name, grade = ("Brad", 95)</span>
<span class="c1"># 如下反复</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">grade</span> <span class="ow">in</span> <span class="n">grades</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">grade</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
</pre></div>
</div>
<p>打印:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Ashley</span>
<span class="mi">93</span>
<span class="n">Brad</span>
<span class="mi">95</span>
<span class="n">Cassie</span>
<span class="mi">84</span>
</pre></div>
</div>
<p>这个for循环代码简洁并非常可读。本文强烈推荐读者在这种情况下使用可迭代物解包。</p>
<p>可迭代物解包的行为有时并不如此易懂。假如你试图将一个有10个对象的可迭代物解包到4个变量时会发生什么?虽然我们之前讨论的内容概括了最基础的解包方式,知道<a class="reference external" href="https://www.python.org/dev/peps/pep-3132/#specification">Python提供更加全面复杂的可迭代物解包语法</a>这一事实也是很有帮助的。我们会在之后看到解包在创建和使用函数时的用处。</p>
<div class="admonition note">
<p class="admonition-title fa fa-exclamation-circle"><strong>经验</strong>:</p>
<p>Python为“解包”(unpack)可迭代物内容——将每个成员赋值给它对应的变量——提供了轻便的语法。这允许我们在for循环可迭代物集合时编写易懂易读的代码。</p>
</div>
</div>
<div class="section" id="枚举可迭代物">
<h3>枚举可迭代物<a class="headerlink" href="#枚举可迭代物" title="永久链接至标题">¶</a></h3>
<p>内置的<a class="reference external" href="https://docs.python.org/3/library/functions.html#enumerate">enumerate</a>(枚举)函数允许我们在迭代时获取可迭代物成员在迭代过程中的位置:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 简单使用 `enumerate`</span>
<span class="o">>>></span> <span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="s2">"abcd"</span><span class="p">):</span>
<span class="o">...</span> <span class="nb">print</span><span class="p">(</span><span class="n">entry</span><span class="p">)</span>
<span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">)</span>
<span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
<span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">)</span>
<span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="s1">'d'</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">enumerate</span></code> 函数接受一个可迭代物并返回一个新的可迭代物,其成员为包含迭代位置和对应成员的元组。如此,我们在枚举这个可迭代物的成员。为了演示此功能的用处,假设我们想要记录列表中所有成员值为 <code class="docutils literal notranslate"><span class="pre">None</span></code> 的索引。我们可以通过在for循环迭代列表时记录迭代位置来达到这个目的。</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 记录可迭代物中值为 `None` 的成员的位置</span>
<span class="n">none_indices</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">iter_cnt</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># 手动记录迭代位置</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">]:</span>
<span class="k">if</span> <span class="n">item</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">none_indices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">iter_cnt</span><span class="p">)</span>
<span class="n">iter_cnt</span> <span class="o">=</span> <span class="n">iter_cnt</span> <span class="o">+</span> <span class="mi">1</span>
<span class="c1"># `none_indices` 现在存储 [1, 3]</span>
</pre></div>
</div>
<p>利用 <code class="docutils literal notranslate"><span class="pre">enumerate</span></code> 和元组解包,我们可以简化此代码并避免使用 <code class="docutils literal notranslate"><span class="pre">iter_cnt</span></code> 这个变量。</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># 使用 `enumerate` 函数来记录迭代位置</span>
<span class="n">none_indices</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># 请注意这里的可迭代物解包!</span>
<span class="k">for</span> <span class="n">iter_cnt</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">]):</span>
<span class="k">if</span> <span class="n">item</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">none_indices</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">iter_cnt</span><span class="p">)</span>
<span class="c1"># `none_indices` 现在存储 [1, 3]</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title fa fa-exclamation-circle"><strong>经验</strong>:</p>
<p>内置的<a class="reference external" href="https://docs.python.org/3/library/functions.html#enumerate">enumerate</a>函数应在任何需要记录for循环迭代位置的情况下(和可迭代物解包一起)使用。和元组解包一起使用会更加简化代码。</p>
</div>
<div class="admonition note">
<p class="admonition-title fa fa-exclamation-circle"><strong>阅读理解:enumerate</strong></p>
<p>在for循环中使用可迭代物 <code class="docutils literal notranslate"><span class="pre">"abcd"</span></code>,<code class="docutils literal notranslate"><span class="pre">enumerate</span></code> 函数,以及元组解包来创建以下列表:<code class="docutils literal notranslate"><span class="pre">[(0,</span> <span class="pre">'a'),</span> <span class="pre">(1,</span> <span class="pre">'b'),</span> <span class="pre">(2,</span> <span class="pre">'c'),</span> <span class="pre">(3,</span> <span class="pre">'d')]</span></code></p>
</div>
<div class="admonition note">
<p class="admonition-title fa fa-exclamation-circle"><strong>阅读理解:是否顺序排列?</strong></p>
<p>使用控制流和循环工具来检查某个成员为数字的可迭代物是否顺序排列。</p>
<p>将变量 <code class="docutils literal notranslate"><span class="pre">unsorted_index</span></code> 初始化为 <code class="docutils literal notranslate"><span class="pre">None</span></code>。如果可迭代物<em>不</em>顺序,那 <code class="docutils literal notranslate"><span class="pre">unsorted_index</span></code> 应该存储序列<em>第一个</em>不符合顺序的成员的索引。如果可迭代物顺序排列,那 <code class="docutils literal notranslate"><span class="pre">unsorted_index</span></code> 应该在最后依然为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,且你的代码应该打印 “sorted!”。</p>
<p>比如说:</p>
<ul class="simple">
<li><p>设可迭代物 <code class="docutils literal notranslate"><span class="pre">my_list</span> <span class="pre">=</span> <span class="pre">[0,</span> <span class="pre">1,</span> <span class="pre">-10,</span> <span class="pre">2]</span></code>,<code class="docutils literal notranslate"><span class="pre">unsorted_index</span></code> 应该为 <code class="docutils literal notranslate"><span class="pre">2</span></code>。</p></li>
<li><p>设可迭代物 <code class="docutils literal notranslate"><span class="pre">my_list</span> <span class="pre">=</span> <span class="pre">[-1,</span> <span class="pre">0,</span> <span class="pre">3,</span> <span class="pre">6]</span></code>,<code class="docutils literal notranslate"><span class="pre">unsorted_index</span></code> 应该为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,且你的代码应该打印 “sorted!”。</p></li>
</ul>
</div>
</div>
</div>
<div class="section" id="官方说明文档链接">
<h2>官方说明文档链接<a class="headerlink" href="#官方说明文档链接" title="永久链接至标题">¶</a></h2>
<ul class="simple">
<li><p><a class="reference external" href="https://docs.python.org/3/glossary.html#term-iterable">可迭代物定义</a></p></li>
<li><p><a class="reference external" href="https://docs.python.org/3/howto/functional.html#built-in-functions">操作可迭代物的函数</a></p></li>
<li><p><a class="reference external" href="https://docs.python.org/3/library/functions.html#enumerate">枚举</a></p></li>
</ul>
</div>
<div class="section" id="阅读理解答案">
<h2>阅读理解答案<a class="headerlink" href="#阅读理解答案" title="永久链接至标题">¶</a></h2>
<p><strong>enumerate:解</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">out</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">num</span><span class="p">,</span> <span class="n">letter</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="s2">"abcd"</span><span class="p">):</span>
<span class="n">out</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">num</span><span class="p">,</span> <span class="n">letter</span><span class="p">))</span>
</pre></div>
</div>
<p><strong>是否顺序排列?:解</strong></p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="n">unsorted_index</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">current_num</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">my_list</span><span class="p">):</span>
<span class="k">if</span> <span class="n">index</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">prev_num</span> <span class="o">=</span> <span class="n">current_num</span>
<span class="k">elif</span> <span class="n">prev_num</span> <span class="o">></span> <span class="n">current_num</span><span class="p">:</span>
<span class="n">unsorted_index</span> <span class="o">=</span> <span class="n">index</span>
<span class="k">break</span>
<span class="n">prev_num</span> <span class="o">=</span> <span class="n">current_num</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"sorted!"</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="Generators_and_Comprehensions.html" class="btn btn-neutral float-right" title="生成器和理解表达式" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="ForLoops.html" class="btn btn-neutral float-left" title="For循环和While循环" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
© Copyright 2019, Ryan Soklaski
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>