forked from sixu05202004/pythontutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
/
datastructures.html
632 lines (612 loc) · 73.2 KB
/
datastructures.html
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
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>5. 数据结构 — Python tutorial 2.7 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '2.7',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Python tutorial 2.7 documentation" href="index.html" />
<link rel="next" title="6. 模块" href="modules.html" />
<link rel="prev" title="4. 深入 Python 流程控制" href="controlflow.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="modules.html" title="6. 模块"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="controlflow.html" title="4. 深入 Python 流程控制"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Python tutorial 2.7 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="tut-structures">
<span id="id1"></span><h1>5. 数据结构<a class="headerlink" href="#tut-structures" title="Permalink to this headline">¶</a></h1>
<p>本章详细讨论了你已经学过的一些知识,同样也添加了一些新内容。</p>
<div class="section" id="tut-morelists">
<span id="id2"></span><h2>5.1. 关于列表更多的内容<a class="headerlink" href="#tut-morelists" title="Permalink to this headline">¶</a></h2>
<p>Python 的列表数据类型包含更多的方法。 这里是所有的列表对象方法:</p>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">append</tt><big>(</big><em>x</em><big>)</big></dt>
<dd><p>把一个元素添加到链表的结尾,相当于 <tt class="docutils literal"><span class="pre">a[len(a):]</span> <span class="pre">=</span> <span class="pre">[x]</span></tt> 。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">extend</tt><big>(</big><em>L</em><big>)</big></dt>
<dd><p>将一个给定列表中的所有元素都添加到另一个列表中,相当于 <tt class="docutils literal"><span class="pre">a[len(a):]</span> <span class="pre">=</span> <span class="pre">L</span></tt> 。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">insert</tt><big>(</big><em>i</em>, <em>x</em><big>)</big></dt>
<dd><p>在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 <tt class="docutils literal"><span class="pre">a.insert(0,</span> <span class="pre">x)</span></tt> 会插入到整个链表之前,而 <tt class="docutils literal"><span class="pre">a.insert(len(a),</span> <span class="pre">x)</span></tt> 相当于 <tt class="docutils literal"><span class="pre">a.append(x)</span></tt> 。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">remove</tt><big>(</big><em>x</em><big>)</big></dt>
<dd><p>删除链表中值为 <em>x</em> 的第一个元素。如果没有这样的元素,就会返回一个错误。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">pop</tt><big>(</big><span class="optional">[</span><em>i</em><span class="optional">]</span><big>)</big></dt>
<dd><p>从链表的指定位置删除元素,并将其返回。如果没有指定索引, <tt class="docutils literal"><span class="pre">a.pop()</span></tt> 返回最后一个元素。元素随即从链表中被删除。(方法中 <em>i</em> 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">index</tt><big>(</big><em>x</em><big>)</big></dt>
<dd><p>返回链表中第一个值为 <em>x</em> 的元素的索引。如果没有匹配的元素就会返回一个错误。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">count</tt><big>(</big><em>x</em><big>)</big></dt>
<dd><p>返回 <em>x</em> 在链表中出现的次数。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">sort</tt><big>(</big><big>)</big></dt>
<dd><p>对链表中的元素就地进行排序。</p>
</dd></dl>
<dl class="method">
<dt>
<tt class="descclassname">list.</tt><tt class="descname">reverse</tt><big>(</big><big>)</big></dt>
<dd><p>就地倒排链表中的元素。</p>
</dd></dl>
<p>下面这个示例演示了链表的大部分方法:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mf">66.25</span><span class="p">,</span> <span class="mi">333</span><span class="p">,</span> <span class="mi">333</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">1234.5</span><span class="p">]</span>
<span class="gp">>>> </span><span class="k">print</span> <span class="n">a</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="mi">333</span><span class="p">),</span> <span class="n">a</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="mf">66.25</span><span class="p">),</span> <span class="n">a</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s">'x'</span><span class="p">)</span>
<span class="go">2 1 0</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">333</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[66.25, 333, -1, 333, 1, 1234.5, 333]</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="mi">333</span><span class="p">)</span>
<span class="go">1</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="mi">333</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[66.25, -1, 333, 1, 1234.5, 333]</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[333, 1234.5, 1, 333, -1, 66.25]</span>
<span class="gp">>>> </span><span class="n">a</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[-1, 1, 66.25, 333, 333, 1234.5]</span>
</pre></div>
</div>
<p>也许大家会发现像 <tt class="docutils literal"><span class="pre">insert</span></tt>, <tt class="docutils literal"><span class="pre">remove</span></tt> 或者 <tt class="docutils literal"><span class="pre">sort</span></tt> 这些修改列表的方法没有打印返回值–它们返回 <tt class="docutils literal"><span class="pre">None</span></tt> 。 在 python 中对所有可变的数据类型这是统一的设计原则。</p>
<div class="section" id="tut-lists-as-stacks">
<span id="id3"></span><h3>5.1.1. 把链表当作堆栈使用<a class="headerlink" href="#tut-lists-as-stacks" title="Permalink to this headline">¶</a></h3>
<p>链表方法使得链表可以很方便的做为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 <tt class="xref py py-meth docutils literal"><span class="pre">append()</span></tt> 方法可以把一个元素添加到堆栈顶。用不指定索引的 <tt class="xref py py-meth docutils literal"><span class="pre">pop()</span></tt> 方法可以把一个元素从堆栈顶释放出来。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">stack</span> <span class="o">=</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">stack</span>
<span class="go">[3, 4, 5, 6, 7]</span>
<span class="gp">>>> </span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="go">7</span>
<span class="gp">>>> </span><span class="n">stack</span>
<span class="go">[3, 4, 5, 6]</span>
<span class="gp">>>> </span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="go">6</span>
<span class="gp">>>> </span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="go">5</span>
<span class="gp">>>> </span><span class="n">stack</span>
<span class="go">[3, 4]</span>
</pre></div>
</div>
</div>
<div class="section" id="tut-lists-as-queues">
<span id="id4"></span><h3>5.1.2. 把链表当作队列使用<a class="headerlink" href="#tut-lists-as-queues" title="Permalink to this headline">¶</a></h3>
<p>你也可以把链表当做队列使用,队列作为特定的数据结构,最先进入的元素最先释放(先进先出)。不过,列表这样用效率不高。相对来说从列表末尾添加和弹出很快;在头部插入和弹出很慢(因为,为了一个元素,要移动整个列表中的所有元素)。</p>
<p>要实现队列,使用 <tt class="xref py py-class docutils literal"><span class="pre">collections.deque</span></tt> ,它为在首尾两端快速插入和删除而设计。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">deque</span>
<span class="gp">>>> </span><span class="n">queue</span> <span class="o">=</span> <span class="n">deque</span><span class="p">([</span><span class="s">"Eric"</span><span class="p">,</span> <span class="s">"John"</span><span class="p">,</span> <span class="s">"Michael"</span><span class="p">])</span>
<span class="gp">>>> </span><span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">"Terry"</span><span class="p">)</span> <span class="c"># Terry arrives</span>
<span class="gp">>>> </span><span class="n">queue</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">"Graham"</span><span class="p">)</span> <span class="c"># Graham arrives</span>
<span class="gp">>>> </span><span class="n">queue</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span> <span class="c"># The first to arrive now leaves</span>
<span class="go">'Eric'</span>
<span class="gp">>>> </span><span class="n">queue</span><span class="o">.</span><span class="n">popleft</span><span class="p">()</span> <span class="c"># The second to arrive now leaves</span>
<span class="go">'John'</span>
<span class="gp">>>> </span><span class="n">queue</span> <span class="c"># Remaining queue in order of arrival</span>
<span class="go">deque(['Michael', 'Terry', 'Graham'])</span>
</pre></div>
</div>
</div>
<div class="section" id="tut-functional">
<span id="id5"></span><h3>5.1.3. 函数式编程工具<a class="headerlink" href="#tut-functional" title="Permalink to this headline">¶</a></h3>
<p>对于链表来讲,有三个内置函数非常有用: <tt class="xref py py-func docutils literal"><span class="pre">filter()</span></tt>, <tt class="xref py py-func docutils literal"><span class="pre">map()</span></tt>, 以及 <tt class="xref py py-func docutils literal"><span class="pre">reduce()</span></tt>。</p>
<p><tt class="docutils literal"><span class="pre">filter(function,</span> <span class="pre">sequence)</span></tt> 返回一个 sequence(序列),包括了给定序列中所有调用 <tt class="docutils literal"><span class="pre">function(item)</span></tt> 后返回值为 true 的元素。(如果可能的话,会返回相同的类型)。如果该 <em>序列</em> (sequence) 是一个 <tt class="xref py py-class docutils literal"><span class="pre">string</span></tt> (字符串)或者 <tt class="xref py py-class docutils literal"><span class="pre">tuple</span></tt> (元组),返回值必定是同一类型,否则,它总是 <tt class="xref py py-class docutils literal"><span class="pre">list</span></tt> 。例如,以下程序可以计算部分素数:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="n">x</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">!=</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">x</span> <span class="o">%</span> <span class="mi">3</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">filter</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">25</span><span class="p">))</span>
<span class="go">[5, 7, 11, 13, 17, 19, 23]</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">map(function,</span> <span class="pre">sequence)</span></tt> 为每一个元素依次调用 <tt class="docutils literal"><span class="pre">function(item)</span></tt> 并将返回值组成一个链表返回。例如,以下程序计算立方:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">cube</span><span class="p">(</span><span class="n">x</span><span class="p">):</span> <span class="k">return</span> <span class="n">x</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">x</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">map</span><span class="p">(</span><span class="n">cube</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">))</span>
<span class="go">[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]</span>
</pre></div>
</div>
<p>可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数(如果某些序列比其它的短,就用 <tt class="docutils literal"><span class="pre">None</span></tt> 来代替)。如果把 <tt class="docutils literal"><span class="pre">None</span></tt> 做为一个函数传入,则直接返回参数做为替代。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">seq</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
<span class="gp">>>> </span><span class="k">def</span> <span class="nf">add</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="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">map</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="n">seq</span><span class="p">,</span> <span class="n">seq</span><span class="p">)</span>
<span class="go">[0, 2, 4, 6, 8, 10, 12, 14]</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">reduce(function,</span> <span class="pre">sequence)</span></tt> 返回一个单值,它是这样构造的:首先以序列的前两个元素调用函数 <em>function</em>,再以返回值和第三个参数调用,依次执行下去。例如,以下程序计算 1 到 10 的整数之和:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">add</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="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">reduce</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">))</span>
<span class="go">55</span>
</pre></div>
</div>
<p>如果序列中只有一个元素,就返回它,如果序列是空的,就抛出一个异常。</p>
<p>可以传入第三个参数作为初始值。如果序列是空的,就返回初始值,否则函数会先接收初始值和序列的第一个元素,然后是返回值和下一个元素,依此类推。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">sum</span><span class="p">(</span><span class="n">seq</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">def</span> <span class="nf">add</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="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
<span class="gp">... </span> <span class="k">return</span> <span class="nb">reduce</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="n">seq</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="nb">sum</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">))</span>
<span class="go">55</span>
<span class="gp">>>> </span><span class="nb">sum</span><span class="p">([])</span>
<span class="go">0</span>
</pre></div>
</div>
<p>不要像示例中这样定义 <tt class="xref py py-func docutils literal"><span class="pre">sum()</span></tt> :因为合计数值是一个通用的需求,早已有内置的 <tt class="docutils literal"><span class="pre">sum(sequence)</span></tt> 函数,非常好用。</p>
</div>
<div class="section" id="tut-listcomps">
<span id="id6"></span><h3>5.1.4. 列表推导式<a class="headerlink" href="#tut-listcomps" title="Permalink to this headline">¶</a></h3>
<p>列表推导式为从序列中创建列表提供了一个简单的方法。 普通的应用程序通过将一些操作应用于序列的每个成员并通过返回的元素创建列表,或者通过满足特定条件的元素创建子序列。</p>
<p>例如, 假设我们创建一个 squares 列表, 可以像下面方式:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">squares</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="gp">... </span> <span class="n">squares</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">squares</span>
<span class="go">[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</span>
</pre></div>
</div>
<p>我们同样能够达到目的采用下面的方式:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">squares</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
</pre></div>
</div>
<p>这也相当于 <tt class="docutils literal"><span class="pre">squares</span> <span class="pre">=</span> <span class="pre">map(lambda</span> <span class="pre">x:</span> <span class="pre">x**2,</span> <span class="pre">range(10))</span></tt>,
但是上面的方式显得简洁以及具有可读性.</p>
<p>列表推导式由包含一个表达式的括号组成,表达式后面跟随一个 <tt class="xref std std-keyword docutils literal"><span class="pre">for</span></tt> 子句,之后可以有零或多个 <tt class="xref std std-keyword docutils literal"><span class="pre">for</span></tt> 或 <tt class="xref std std-keyword docutils literal"><span class="pre">if</span></tt> 子句。 结果是一个列表,由表达式依据其后面的 <tt class="xref std std-keyword docutils literal"><span class="pre">for</span></tt> 和 <tt class="xref std std-keyword docutils literal"><span class="pre">if</span></tt> 子句上下文计算而来的结果构成。</p>
<p>例如,如下的列表推导式结合两个列表的元素,如果元素之间不相等的话:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </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="k">for</span> <span class="n">x</span> <span class="ow">in</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="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">]</span> <span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="n">y</span><span class="p">]</span>
<span class="go">[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]</span>
</pre></div>
</div>
<p>等同于:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">combs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">x</span> <span class="ow">in</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="gp">... </span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">]:</span>
<span class="gp">... </span> <span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="n">y</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">combs</span><span class="o">.</span><span class="n">append</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="gp">...</span>
<span class="gp">>>> </span><span class="n">combs</span>
<span class="go">[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]</span>
</pre></div>
</div>
<p>值得注意的是在上面两个方法中的 <tt class="xref std std-keyword docutils literal"><span class="pre">for</span></tt> 和 <tt class="xref std std-keyword docutils literal"><span class="pre">if</span></tt> 语句的顺序。</p>
<p>如果想要得到一个元组,必须要加上括号:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">vec</span> <span class="o">=</span> <span class="p">[</span><span class="o">-</span><span class="mi">4</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
<span class="gp">>>> </span><span class="c"># create a new list with the values doubled</span>
<span class="gp">>>> </span><span class="p">[</span><span class="n">x</span><span class="o">*</span><span class="mi">2</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">vec</span><span class="p">]</span>
<span class="go">[-8, -4, 0, 4, 8]</span>
<span class="gp">>>> </span><span class="c"># filter the list to exclude negative numbers</span>
<span class="gp">>>> </span><span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">vec</span> <span class="k">if</span> <span class="n">x</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">]</span>
<span class="go">[0, 2, 4]</span>
<span class="gp">>>> </span><span class="c"># apply a function to all the elements</span>
<span class="gp">>>> </span><span class="p">[</span><span class="nb">abs</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">vec</span><span class="p">]</span>
<span class="go">[4, 2, 0, 2, 4]</span>
<span class="gp">>>> </span><span class="c"># call a method on each element</span>
<span class="gp">>>> </span><span class="n">freshfruit</span> <span class="o">=</span> <span class="p">[</span><span class="s">' banana'</span><span class="p">,</span> <span class="s">' loganberry '</span><span class="p">,</span> <span class="s">'passion fruit '</span><span class="p">]</span>
<span class="gp">>>> </span><span class="p">[</span><span class="n">weapon</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">weapon</span> <span class="ow">in</span> <span class="n">freshfruit</span><span class="p">]</span>
<span class="go">['banana', 'loganberry', 'passion fruit']</span>
<span class="gp">>>> </span><span class="c"># create a list of 2-tuples like (number, square)</span>
<span class="gp">>>> </span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">6</span><span class="p">)]</span>
<span class="go">[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]</span>
<span class="gp">>>> </span><span class="c"># the tuple must be parenthesized, otherwise an error is raised</span>
<span class="gp">>>> </span><span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">6</span><span class="p">)]</span>
<span class="go"> File "<stdin>", line 1, in ?</span>
<span class="go"> [x, x**2 for x in range(6)]</span>
<span class="go"> ^</span>
<span class="go">SyntaxError: invalid syntax</span>
<span class="gp">>>> </span><span class="c"># flatten a list using a listcomp with two 'for'</span>
<span class="gp">>>> </span><span class="n">vec</span> <span class="o">=</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="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">],</span> <span class="p">[</span><span class="mi">7</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="gp">>>> </span><span class="p">[</span><span class="n">num</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">vec</span> <span class="k">for</span> <span class="n">num</span> <span class="ow">in</span> <span class="n">elem</span><span class="p">]</span>
<span class="go">[1, 2, 3, 4, 5, 6, 7, 8, 9]</span>
</pre></div>
</div>
<p>列表推导式可使用复杂的表达式和嵌套函数:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">pi</span>
<span class="gp">>>> </span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="n">pi</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">)]</span>
<span class="go">['3.1', '3.14', '3.142', '3.1416', '3.14159']</span>
</pre></div>
</div>
<div class="section" id="id7">
<h4>5.1.4.1. 嵌套的列表推导式<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h4>
<p>列表推导式可以嵌套。</p>
<p>考虑以下的 3x4 矩阵, 一个列表中包含三个长度为4的列表:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">matrix</span> <span class="o">=</span> <span class="p">[</span>
<span class="gp">... </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">4</span><span class="p">],</span>
<span class="gp">... </span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">],</span>
<span class="gp">... </span> <span class="p">[</span><span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">],</span>
<span class="gp">... </span><span class="p">]</span>
</pre></div>
</div>
<p>现在,如果你想交换行和列,可以用嵌套的列表推导式:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="p">[[</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">matrix</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)]</span>
<span class="go">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</span>
</pre></div>
</div>
<p>像前面看到的,嵌套的列表推导式是对 <tt class="xref std std-keyword docutils literal"><span class="pre">for</span></tt> 后面的内容进行求值,所以上例就等价于:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">transposed</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">):</span>
<span class="gp">... </span> <span class="n">transposed</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">matrix</span><span class="p">])</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">transposed</span>
<span class="go">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</span>
</pre></div>
</div>
<p>反过来说,如下也是一样的:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">transposed</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">):</span>
<span class="gp">... </span> <span class="c"># the following 3 lines implement the nested listcomp</span>
<span class="gp">... </span> <span class="n">transposed_row</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">... </span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">matrix</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">transposed_row</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="gp">... </span> <span class="n">transposed</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">transposed_row</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">transposed</span>
<span class="go">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</span>
</pre></div>
</div>
<p>在实际中,你应该更喜欢使用内置函数组成复杂流程语句。 对此种情况 <tt class="xref py py-func docutils literal"><span class="pre">zip()</span></tt> 函数将会做的更好:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">matrix</span><span class="p">))</span>
<span class="go">[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]</span>
</pre></div>
</div>
<p>更多关于本行中使用的星号的说明,参考 <a class="reference internal" href="controlflow.html#tut-unpacking-arguments"><em>参数列表的分拆</em></a> 。</p>
</div>
</div>
</div>
<div class="section" id="del">
<span id="tut-del"></span><h2>5.2. <tt class="xref std std-keyword docutils literal"><span class="pre">del</span></tt> 语句<a class="headerlink" href="#del" title="Permalink to this headline">¶</a></h2>
<p>有个方法可以从列表中按给定的索引而不是值来删除一个子项: <tt class="xref std std-keyword docutils literal"><span class="pre">del</span></tt> 语句。它不同于有返回值的 <tt class="xref py py-meth docutils literal"><span class="pre">pop()</span></tt> 方法。语句 <tt class="xref std std-keyword docutils literal"><span class="pre">del</span></tt> 还可以从列表中删除切片或清空整个列表(我们以前介绍过一个方法是将空列表赋值给列表的切片)。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">66.25</span><span class="p">,</span> <span class="mi">333</span><span class="p">,</span> <span class="mi">333</span><span class="p">,</span> <span class="mf">1234.5</span><span class="p">]</span>
<span class="gp">>>> </span><span class="k">del</span> <span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[1, 66.25, 333, 333, 1234.5]</span>
<span class="gp">>>> </span><span class="k">del</span> <span class="n">a</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">4</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[1, 66.25, 1234.5]</span>
<span class="gp">>>> </span><span class="k">del</span> <span class="n">a</span><span class="p">[:]</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">[]</span>
</pre></div>
</div>
<p><tt class="xref std std-keyword docutils literal"><span class="pre">del</span></tt> 也可以删除整个变量:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">del</span> <span class="n">a</span>
</pre></div>
</div>
<p>此后再引用命名 <tt class="docutils literal"><span class="pre">a</span></tt> 会引发错误(直到另一个值赋给它为止)。我们在后面的内容中可以看到 <tt class="xref std std-keyword docutils literal"><span class="pre">del</span></tt> 的其它用法。</p>
</div>
<div class="section" id="tut-tuples">
<span id="id8"></span><h2>5.3. 元组和序列<a class="headerlink" href="#tut-tuples" title="Permalink to this headline">¶</a></h2>
<p>我们知道链表和字符串有很多通用的属性,例如索引和切割操作。它们是 序列 类型(参见 <em class="xref std std-ref">typesseq</em> )中的两种。因为 Python 是一个在不断进化的语言,也可能会加入其它的序列类型,这里介绍另一种标准序列类型: <em>元组</em> 。</p>
<p>一个元组由数个逗号分隔的值组成,例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">t</span> <span class="o">=</span> <span class="mi">12345</span><span class="p">,</span> <span class="mi">54321</span><span class="p">,</span> <span class="s">'hello!'</span>
<span class="gp">>>> </span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="go">12345</span>
<span class="gp">>>> </span><span class="n">t</span>
<span class="go">(12345, 54321, 'hello!')</span>
<span class="gp">>>> </span><span class="c"># Tuples may be nested:</span>
<span class="gp">... </span><span class="n">u</span> <span class="o">=</span> <span class="n">t</span><span class="p">,</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">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">u</span>
<span class="go">((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))</span>
<span class="gp">>>> </span><span class="c"># Tuples are immutable:</span>
<span class="gp">... </span><span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">88888</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">TypeError</span>: <span class="n">'tuple' object does not support item assignment</span>
<span class="gp">>>> </span><span class="c"># but they can contain mutable objects:</span>
<span class="gp">... </span><span class="n">v</span> <span class="o">=</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="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
<span class="gp">>>> </span><span class="n">v</span>
<span class="go">([1, 2, 3], [3, 2, 1])</span>
</pre></div>
</div>
<p>如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可以有或没有括号,不过经常括号都是必须的(如果元组是一个更大的表达式的一部分)。不能给元组的一个独立的元素赋值(尽管你可以通过联接和切割来模拟)。还可以创建包含可变对象的元组,例如链表。</p>
<p>虽然元组和列表很类似,它们经常被用来在不同的情况和不同的用途。元组有很多用途。例如 (x, y) 坐标对,数据库中的员工记录等等。元组就像字符串,不可改变。</p>
<p>一个特殊的问题是构造包含零个或一个元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值不够明确)。丑陋,但是有效。例如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">empty</span> <span class="o">=</span> <span class="p">()</span>
<span class="gp">>>> </span><span class="n">singleton</span> <span class="o">=</span> <span class="s">'hello'</span><span class="p">,</span> <span class="c"># <-- note trailing comma</span>
<span class="gp">>>> </span><span class="nb">len</span><span class="p">(</span><span class="n">empty</span><span class="p">)</span>
<span class="go">0</span>
<span class="gp">>>> </span><span class="nb">len</span><span class="p">(</span><span class="n">singleton</span><span class="p">)</span>
<span class="go">1</span>
<span class="gp">>>> </span><span class="n">singleton</span>
<span class="go">('hello',)</span>
</pre></div>
</div>
<p>语句 <tt class="docutils literal"><span class="pre">t</span> <span class="pre">=</span> <span class="pre">12345,</span> <span class="pre">54321,</span> <span class="pre">'hello!'</span></tt> 是 <em>元组封装</em> (tuple packing)的一个例子:值 <tt class="docutils literal"><span class="pre">12345</span></tt> , <tt class="docutils literal"><span class="pre">54321</span></tt> 和 <tt class="docutils literal"><span class="pre">'hello!'</span></tt> 被封装进元组。其逆操作可能是这样:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </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">t</span>
</pre></div>
</div>
<p>这个调用等号右边可以是任何线性序列,称之为 <em>序列拆封</em> 非常恰当。序列拆封要求左侧的变量数目与序列的元素个数相同。要注意的是可变参数(multiple assignment )其实只是元组封装和序列拆封的一个结合。</p>
</div>
<div class="section" id="tut-sets">
<span id="id9"></span><h2>5.4. 集合<a class="headerlink" href="#tut-sets" title="Permalink to this headline">¶</a></h2>
<p>Python 还包含了一个数据类型 <em>set</em> (集合) 。集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。集合对象还支持 union(联合),intersection(交),difference(差)和 sysmmetric difference(对称差集)等数学运算。</p>
<p>大括号或 <tt class="xref py py-func docutils literal"><span class="pre">set()</span></tt> 函数可以用来创建集合。 注意:想要创建空集合,你必须使用 <tt class="docutils literal"><span class="pre">set()</span></tt> 而不是 <tt class="docutils literal"><span class="pre">{}</span></tt> 。后者用于创建空字典,我们在下一节中介绍的一种数据结构。</p>
<p>以下是一个简单的演示:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">basket</span> <span class="o">=</span> <span class="p">[</span><span class="s">'apple'</span><span class="p">,</span> <span class="s">'orange'</span><span class="p">,</span> <span class="s">'apple'</span><span class="p">,</span> <span class="s">'pear'</span><span class="p">,</span> <span class="s">'orange'</span><span class="p">,</span> <span class="s">'banana'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">fruit</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">basket</span><span class="p">)</span> <span class="c"># create a set without duplicates</span>
<span class="gp">>>> </span><span class="n">fruit</span>
<span class="go">set(['orange', 'pear', 'apple', 'banana'])</span>
<span class="gp">>>> </span><span class="s">'orange'</span> <span class="ow">in</span> <span class="n">fruit</span> <span class="c"># fast membership testing</span>
<span class="go">True</span>
<span class="gp">>>> </span><span class="s">'crabgrass'</span> <span class="ow">in</span> <span class="n">fruit</span>
<span class="go">False</span>
<span class="gp">>>> </span><span class="c"># Demonstrate set operations on unique letters from two words</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">'abracadabra'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">b</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="s">'alacazam'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="c"># unique letters in a</span>
<span class="go">set(['a', 'r', 'b', 'c', 'd'])</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="o">-</span> <span class="n">b</span> <span class="c"># letters in a but not in b</span>
<span class="go">set(['r', 'd', 'b'])</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="o">|</span> <span class="n">b</span> <span class="c"># letters in either a or b</span>
<span class="go">set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="o">&</span> <span class="n">b</span> <span class="c"># letters in both a and b</span>
<span class="go">set(['a', 'c'])</span>
<span class="gp">>>> </span><span class="n">a</span> <span class="o">^</span> <span class="n">b</span> <span class="c"># letters in a or b but not both</span>
<span class="go">set(['r', 'd', 'b', 'm', 'z', 'l'])</span>
</pre></div>
</div>
<p>类似 <a class="reference internal" href="#tut-listcomps"><em>for lists</em></a> ,这里有一种集合推导式语法:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="p">{</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="s">'abracadabra'</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">not</span> <span class="ow">in</span> <span class="s">'abc'</span><span class="p">}</span>
<span class="gp">>>> </span><span class="n">a</span>
<span class="go">{'r', 'd'}</span>
</pre></div>
</div>
</div>
<div class="section" id="tut-dictionaries">
<span id="id10"></span><h2>5.5. 字典<a class="headerlink" href="#tut-dictionaries" title="Permalink to this headline">¶</a></h2>
<p>另一个非常有用的 Python 内建数据类型是 <em>字典</em> (参见 <em class="xref std std-ref">typesmapping</em> )。字典在某些语言中可能称为 联合内存 ( associative memories )或 联合数组 ( associative arrays )。序列是以连续的整数为索引,与此不同的是,字典以 <em>关键字</em> 为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以作为关键字,如果它直接或间接地包含了可变对象,就不能当做关键字。不能用链表做关键字,因为链表可以用索引、切割或者 <tt class="xref py py-meth docutils literal"><span class="pre">append()</span></tt> 和 <tt class="xref py py-meth docutils literal"><span class="pre">extend()</span></tt> 等方法改变。</p>
<p>理解字典的最佳方式是把它看做无序的键: <em>值对</em> (key:value pairs)集合,键必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典: <tt class="docutils literal"><span class="pre">{}</span></tt> 。初始化链表时,在大括号内放置一组逗号分隔的键:值对,这也是字典输出的方式。</p>
<p>字典的主要操作是依据键来存储和析取值。也可以用 <tt class="docutils literal"><span class="pre">del</span></tt> 来删除键:值对(key:value)。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图从一个不存在的键中取值会导致错误。</p>
<p>对一个字典执行 <tt class="xref py py-meth docutils literal"><span class="pre">keys()</span></tt> 将返回一个字典中所有关键字组成的无序列表(如果你想要排序,只需使用 <tt class="xref py py-func docutils literal"><span class="pre">sorted()</span></tt>)。使用 <tt class="xref std std-keyword docutils literal"><span class="pre">in</span></tt> 关键字(指 Python 语法)可以检查字典中是否存在某个关键字(指字典)。</p>
<p>这里是使用字典的一个小示例:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">tel</span> <span class="o">=</span> <span class="p">{</span><span class="s">'jack'</span><span class="p">:</span> <span class="mi">4098</span><span class="p">,</span> <span class="s">'sape'</span><span class="p">:</span> <span class="mi">4139</span><span class="p">}</span>
<span class="gp">>>> </span><span class="n">tel</span><span class="p">[</span><span class="s">'guido'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">4127</span>
<span class="gp">>>> </span><span class="n">tel</span>
<span class="go">{'sape': 4139, 'guido': 4127, 'jack': 4098}</span>
<span class="gp">>>> </span><span class="n">tel</span><span class="p">[</span><span class="s">'jack'</span><span class="p">]</span>
<span class="go">4098</span>
<span class="gp">>>> </span><span class="k">del</span> <span class="n">tel</span><span class="p">[</span><span class="s">'sape'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">tel</span><span class="p">[</span><span class="s">'irv'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">4127</span>
<span class="gp">>>> </span><span class="n">tel</span>
<span class="go">{'guido': 4127, 'irv': 4127, 'jack': 4098}</span>
<span class="gp">>>> </span><span class="n">tel</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
<span class="go">['guido', 'irv', 'jack']</span>
<span class="gp">>>> </span><span class="s">'guido'</span> <span class="ow">in</span> <span class="n">tel</span>
<span class="go">True</span>
</pre></div>
</div>
<p><tt class="xref py py-func docutils literal"><span class="pre">dict()</span></tt> 构造函数可以直接从 key-value 对中创建字典:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nb">dict</span><span class="p">([(</span><span class="s">'sape'</span><span class="p">,</span> <span class="mi">4139</span><span class="p">),</span> <span class="p">(</span><span class="s">'guido'</span><span class="p">,</span> <span class="mi">4127</span><span class="p">),</span> <span class="p">(</span><span class="s">'jack'</span><span class="p">,</span> <span class="mi">4098</span><span class="p">)])</span>
<span class="go">{'sape': 4139, 'jack': 4098, 'guido': 4127}</span>
</pre></div>
</div>
<p>此外,字典推导式可以从任意的键值表达式中创建字典:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="p">{</span><span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">)}</span>
<span class="go">{2: 4, 4: 16, 6: 36}</span>
</pre></div>
</div>
<p>如果关键字都是简单的字符串,有时通过关键字参数指定 key-value 对更为方便:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nb">dict</span><span class="p">(</span><span class="n">sape</span><span class="o">=</span><span class="mi">4139</span><span class="p">,</span> <span class="n">guido</span><span class="o">=</span><span class="mi">4127</span><span class="p">,</span> <span class="n">jack</span><span class="o">=</span><span class="mi">4098</span><span class="p">)</span>
<span class="go">{'sape': 4139, 'jack': 4098, 'guido': 4127}</span>
</pre></div>
</div>
</div>
<div class="section" id="tut-loopidioms">
<span id="id11"></span><h2>5.6. 循环技巧<a class="headerlink" href="#tut-loopidioms" title="Permalink to this headline">¶</a></h2>
<p>在序列中循环时,索引位置和对应值可以使用 <tt class="xref py py-func docutils literal"><span class="pre">enumerate()</span></tt> 函数同时得到:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span><span class="s">'tic'</span><span class="p">,</span> <span class="s">'tac'</span><span class="p">,</span> <span class="s">'toe'</span><span class="p">]):</span>
<span class="gp">... </span> <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">0 tic</span>
<span class="go">1 tac</span>
<span class="go">2 toe</span>
</pre></div>
</div>
<p>同时循环两个或更多的序列,可以使用 <tt class="xref py py-func docutils literal"><span class="pre">zip()</span></tt> 整体打包:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">questions</span> <span class="o">=</span> <span class="p">[</span><span class="s">'name'</span><span class="p">,</span> <span class="s">'quest'</span><span class="p">,</span> <span class="s">'favorite color'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">answers</span> <span class="o">=</span> <span class="p">[</span><span class="s">'lancelot'</span><span class="p">,</span> <span class="s">'the holy grail'</span><span class="p">,</span> <span class="s">'blue'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">q</span><span class="p">,</span> <span class="n">a</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">questions</span><span class="p">,</span> <span class="n">answers</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">print</span> <span class="s">'What is your {0}? It is {1}.'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">a</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">What is your name? It is lancelot.</span>
<span class="go">What is your quest? It is the holy grail.</span>
<span class="go">What is your favorite color? It is blue.</span>
</pre></div>
</div>
<p>需要逆向循环序列的话,先正向定位序列,然后调用 <tt class="xref py py-func docutils literal"><span class="pre">reversed()</span></tt> 函数:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">xrange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">2</span><span class="p">)):</span>
<span class="gp">... </span> <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">9</span>
<span class="go">7</span>
<span class="go">5</span>
<span class="go">3</span>
<span class="go">1</span>
</pre></div>
</div>
<p>要按排序后的顺序循环序列的话,使用 <tt class="xref py py-func docutils literal"><span class="pre">sorted()</span></tt> 函数,它不改动原序列,而是生成一个新的已排序的序列:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">basket</span> <span class="o">=</span> <span class="p">[</span><span class="s">'apple'</span><span class="p">,</span> <span class="s">'orange'</span><span class="p">,</span> <span class="s">'apple'</span><span class="p">,</span> <span class="s">'pear'</span><span class="p">,</span> <span class="s">'orange'</span><span class="p">,</span> <span class="s">'banana'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">basket</span><span class="p">)):</span>
<span class="gp">... </span> <span class="k">print</span> <span class="n">f</span>
<span class="gp">...</span>
<span class="go">apple</span>
<span class="go">banana</span>
<span class="go">orange</span>
<span class="go">pear</span>
</pre></div>
</div>
</div>
<div class="section" id="tut-conditions">
<span id="id12"></span><h2>5.7. 深入条件控制<a class="headerlink" href="#tut-conditions" title="Permalink to this headline">¶</a></h2>
<p><tt class="docutils literal"><span class="pre">while</span></tt> 和 <tt class="docutils literal"><span class="pre">if</span></tt> 语句中使用的条件不仅可以使用比较,而且可以包含任意的操作。</p>
<p>比较操作符 <tt class="docutils literal"><span class="pre">in</span></tt> 和 <tt class="docutils literal"><span class="pre">not</span> <span class="pre">in</span></tt> 用来判断值是否在一个区间之内。操作符 <tt class="docutils literal"><span class="pre">is</span></tt> 和 <tt class="docutils literal"><span class="pre">is</span> <span class="pre">not</span></tt> 比较两个对象是否相同;这只和诸如链表这样的可变对象有关。所有的比较操作符具有相同的优先级,低于所有的数值操作。</p>
<p>比较操作可以传递。例如 <tt class="docutils literal"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">==</span> <span class="pre">c</span></tt> 判断是否 <tt class="docutils literal"><span class="pre">a</span></tt> 小于 <tt class="docutils literal"><span class="pre">b</span></tt> 并且 <tt class="docutils literal"><span class="pre">b</span></tt> 等于 <tt class="docutils literal"><span class="pre">c</span></tt> 。</p>
<p>比较操作可以通过逻辑操作符 <tt class="docutils literal"><span class="pre">and</span></tt> 和 <tt class="docutils literal"><span class="pre">or</span></tt> 组合,比较的结果可以用 <tt class="docutils literal"><span class="pre">not</span></tt> 来取反义。这些操作符的优先级又低于比较操作符,在它们之中,<tt class="docutils literal"><span class="pre">not</span></tt> 具有最高的优先级, <tt class="docutils literal"><span class="pre">or</span></tt> 优先级最低,所以 <tt class="docutils literal"><span class="pre">A</span> <span class="pre">and</span> <span class="pre">not</span> <span class="pre">B</span> <span class="pre">or</span> <span class="pre">C</span></tt> 等于 <tt class="docutils literal"><span class="pre">(A</span> <span class="pre">and</span> <span class="pre">(notB))</span> <span class="pre">or</span> <span class="pre">C</span></tt> 。当然,括号也可以用于比较表达式。</p>
<p>逻辑操作符 <tt class="docutils literal"><span class="pre">and</span></tt> 和 <tt class="docutils literal"><span class="pre">or</span></tt> 也称作 短路操作符 :它们的参数从左向右解析,一旦结果可以确定就停止。例如,如果 <tt class="docutils literal"><span class="pre">A</span></tt> 和 <tt class="docutils literal"><span class="pre">C</span></tt> 为真而 <tt class="docutils literal"><span class="pre">B</span></tt> 为假, <tt class="docutils literal"><span class="pre">A</span> <span class="pre">and</span> <span class="pre">B</span> <span class="pre">and</span> <span class="pre">C</span></tt> 不会解析 <tt class="docutils literal"><span class="pre">C</span></tt> 。作用于一个普通的非逻辑值时,短路操作符的返回值通常是最后一个变量。</p>
<p>可以把比较或其它逻辑表达式的返回值赋给一个变量,例如,</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">string1</span><span class="p">,</span> <span class="n">string2</span><span class="p">,</span> <span class="n">string3</span> <span class="o">=</span> <span class="s">''</span><span class="p">,</span> <span class="s">'Trondheim'</span><span class="p">,</span> <span class="s">'Hammer Dance'</span>
<span class="gp">>>> </span><span class="n">non_null</span> <span class="o">=</span> <span class="n">string1</span> <span class="ow">or</span> <span class="n">string2</span> <span class="ow">or</span> <span class="n">string3</span>
<span class="gp">>>> </span><span class="n">non_null</span>
<span class="go">'Trondheim'</span>
</pre></div>
</div>
<p>需要注意的是 Python 与 C 不同,在表达式内部不能赋值。C 程序员经常对此抱怨,不过它避免了一类在 C 程序中司空见惯的错误:想要在解析式中使 <tt class="docutils literal"><span class="pre">==</span></tt> 时误用了 <tt class="docutils literal"><span class="pre">=</span></tt> 操作符。</p>
</div>
<div class="section" id="tut-comparing">
<span id="id13"></span><h2>5.8. 比较序列和其它类型<a class="headerlink" href="#tut-comparing" title="Permalink to this headline">¶</a></h2>
<p>序列对象可以与相同类型的其它对象比较。比较操作按 <em>字典序</em> 进行:首先比较前两个元素,如果不同,就决定了比较的结果;如果相同,就比较后两个元素,依此类推,直到所有序列都完成比较。如果两个元素本身就是同样类 型的序列,就递归字典序比较。如果两个序列的所有子项都相等,就认为序列相等。如果一个序列是另一个序列的初始子序列,较短的一个序列就小于另一个。字符 串的字典序按照单字符的 ASCII 顺序。下面是同类型序列之间比较的一些例子:</p>
<div class="highlight-python"><div class="highlight"><pre><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="o"><</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">4</span><span class="p">)</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="o"><</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">4</span><span class="p">]</span>
<span class="s">'ABC'</span> <span class="o"><</span> <span class="s">'C'</span> <span class="o"><</span> <span class="s">'Pascal'</span> <span class="o"><</span> <span class="s">'Python'</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">4</span><span class="p">)</span> <span class="o"><</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">4</span><span class="p">)</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="o"><</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="o">-</span><span class="mi">1</span><span class="p">)</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="o">==</span> <span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">,</span> <span class="mf">3.0</span><span class="p">)</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="p">(</span><span class="s">'aa'</span><span class="p">,</span> <span class="s">'ab'</span><span class="p">))</span> <span class="o"><</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="p">(</span><span class="s">'abc'</span><span class="p">,</span> <span class="s">'a'</span><span class="p">),</span> <span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>需要注意的是如果通过 <tt class="docutils literal"><span class="pre"><</span></tt> 或者 <tt class="docutils literal"><span class="pre">></span></tt> 比较的对象只要具有合适的比较方法就是合法的。 比如,混合数值类型是通过它们的数值就行比较的,所以0是等于0.0。 否则解释器将会触发一个 <tt class="xref py py-exc docutils literal"><span class="pre">TypeError</span></tt> 异常,而不是提供一个随意的结果。</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">5. 数据结构</a><ul>
<li><a class="reference internal" href="#tut-morelists">5.1. 关于列表更多的内容</a><ul>
<li><a class="reference internal" href="#tut-lists-as-stacks">5.1.1. 把链表当作堆栈使用</a></li>
<li><a class="reference internal" href="#tut-lists-as-queues">5.1.2. 把链表当作队列使用</a></li>
<li><a class="reference internal" href="#tut-functional">5.1.3. 函数式编程工具</a></li>
<li><a class="reference internal" href="#tut-listcomps">5.1.4. 列表推导式</a><ul>
<li><a class="reference internal" href="#id7">5.1.4.1. 嵌套的列表推导式</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#del">5.2. <tt class="docutils literal"><span class="pre">del</span></tt> 语句</a></li>
<li><a class="reference internal" href="#tut-tuples">5.3. 元组和序列</a></li>
<li><a class="reference internal" href="#tut-sets">5.4. 集合</a></li>
<li><a class="reference internal" href="#tut-dictionaries">5.5. 字典</a></li>
<li><a class="reference internal" href="#tut-loopidioms">5.6. 循环技巧</a></li>
<li><a class="reference internal" href="#tut-conditions">5.7. 深入条件控制</a></li>
<li><a class="reference internal" href="#tut-comparing">5.8. 比较序列和其它类型</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="controlflow.html"
title="previous chapter">4. 深入 Python 流程控制</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="modules.html"
title="next chapter">6. 模块</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/datastructures.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="modules.html" title="6. 模块"
>next</a> |</li>
<li class="right" >
<a href="controlflow.html" title="4. 深入 Python 流程控制"
>previous</a> |</li>
<li><a href="index.html">Python tutorial 2.7 documentation</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2013, D.D.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.1.
</div>
</body>
</html>