📄 node7.html
字号:
<p> </p> <h2> <br> 5.1.2 把列(Lists)当作伫列(Queues)使用 </h2> <p> 你也可以很方便的拿list来当作伫列(queues)来使用。Queues的特点是第一个加入的成员会是第一个被取出的成员(先进先出``first-in, first-out''法则)。要在queue的后端加入一个成员可以使用 <tt class="method">append()</tt> ,要从queue的最前端取出一个成员可以使用 use <tt class="method">pop()</tt> ,记得参数是 <code>0</code> 。例子如下: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> queue = ["Eric", "John", "Michael"]<br>>>> queue.append("Terry") # Terry arrives<br>>>> queue.append("Graham") # Graham arrives<br>>>> queue.pop(0)<br>'Eric'<br>>>> queue.pop(0)<br>'John'<br>>>> queue<br>['Michael', 'Terry', 'Graham']<br></pre> </dd> </dl> <p> </p> <h2> <br> 5.1.3 功能式程式设计工具 </h2> <p> 有三个与list合用非常有用的内建工具函式: <tt class="function">filter()</tt>, <tt class="function">map()</tt>, 以及 <tt class="function">reduce()</tt> 。 </p> <p> "<tt class="samp">filter(<var>function</var>, <var>sequence</var>)</tt>" 这个函式会传回 一个sequence (如果可能的话其成员为同一资料型态),这个sequence里面的成员都是将 <var>sequence</var> 里面的的成员,一一传入到 <code><var>function</var>(<var>item</var>)</code> 所代表的函式后,传回值为true的成员所组合而成。这个函式对于传入的 <var>sequence</var> 有过滤的效果,如下例所示: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> def f(x): return x % 2 != 0 and x % 3 != 0<br>...<br>>>> filter(f, range(2, 25))<br>[5, 7, 11, 13, 17, 19, 23]<br></pre> </dd> </dl> <p> "<tt class="samp">map(<var>function</var>, <var>sequence</var>)</tt>" 会针对 <var>sequence</var> 里的各个成员呼叫 <code><var>function</var>(<var>item</var>)</code> ,然后传回个别成员呼叫之后传回的结果。举例来说,要计算一连串的立方值,我们可以如此做: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> def cube(x): return x*x*x<br>...<br>>>> map(cube, range(1, 11))<br>[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]<br></pre> </dd> </dl> <p> 我们也可以传入不只一个sequence。如果传入多个sequence的话,第一个函式名称的参数要是能够处理多个参数的函式,然后系统会把各个sequence相对应的成员拿出来放入函式之中(如果两个sequence长度不相等的话,不足的会用 <code>None</code> 来补足)。如果第一个函式名称参数为 <code>None</code> 的话,所呼叫的函式就仅仅是传回其所传入的参数。 </p> <p> 综合以上的两个特性,我们可以使用 "<tt class="samp">map(None, <var>list1</var>, <var>list2</var>)</tt>" 这一个工具函式来方便的转换两个sequence成为一个成对的成员组合的sequence。请看例子: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> seq = range(8)<br>>>> def square(x): return x*x<br>...<br>>>> map(None, seq, map(square, seq))<br>[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)]<br></pre> </dd> </dl> <p> "<tt class="samp">reduce(<var>func</var>, <var>sequence</var>)</tt>" 会利用 <var>sequence</var> 的前两个成员当参数呼叫 <var>func</var> ,然后所得的传回值再与下一个成员当参数传入 <var>func</var> ,一直到整个 <var>sequence</var> 结束。下面的例子计算1到10的总和: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> def add(x,y): return x+y<br>...<br>>>> reduce(add, range(1, 11))<br>55<br></pre> </dd> </dl> <p> 如果在 <var>sequence</var> 里面只有一个成员的话,这个成员的值就会直接传回。如果在 <var>sequence</var> 里面没有任何成员的话,会造成一个例外状况(exception)。 </p> <p> 我们也可以加入第三个参数来当作开始的值,如此当传入的 <var>sequence</var> 是空的话,就可以使用这个开始值。如果是正常的sequencde的话,开始值会先跟第一个成员被传入当作呼叫 <var>func</var> 的参数,其传回值再跟第二个成员传入 <var>func</var> ,依此类推。请看下例: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> def sum(seq):<br>... def add(x,y): return x+y<br>... return reduce(add, seq, 0)<br>... <br>>>> sum(range(1, 11))<br>55<br>>>> sum([])<br>0<br></pre> </dd> </dl> <p> </p> <h2><a name="SECTION007140000000000000000"> 5.1.4 传回整个列 (List Comprehensions) </a> </h2> <p> List comprehensions提供了一个制造list简洁的方法,而不用使用 <tt class="function">map()</tt>, <tt class="function">filter()</tt> 以及/或者 <tt class="keyword">lambda</tt> 形式。其结果也比使用以上的方法来做出list要来的清楚易懂。list comprehension通常是一个expression跟着是一个 <tt class="keyword">for</tt> 的语句,然后是零个或多个 <tt class="keyword">for</tt> 或是 <tt class="keyword">if</tt> 语句。其传回的list是一个由在 <tt class="keyword">for</tt> 及 <tt class="keyword">if</tt> 语句条件下执行expression的结果。如果expression的结果是一个tuple,就必须用括号"( )"括起来。 </p> <p> </p> <dl> <dd><pre class="verbatim">>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']<br>>>> [weapon.strip() for weapon in freshfruit]<br>['banana', 'loganberry', 'passion fruit']<br>>>> vec = [2, 4, 6]<br>>>> [3*x for x in vec]<br>[6, 12, 18]<br>>>> [3*x for x in vec if x > 3]<br>[12, 18]<br>>>> [3*x for x in vec if x < 2]<br>[]<br>>>> [{x: x**2} for x in vec]<br>[{2: 4}, {4: 16}, {6: 36}]<br>>>> [[x,x**2] for x in vec]<br>[[2, 4], [4, 16], [6, 36]]<br>>>> [x, x**2 for x in vec] # error - parens required for tuples<br> File "<stdin>", line 1<br> [x, x**2 for x in vec]<br> ^<br>SyntaxError: invalid syntax<br>>>> [(x, x**2) for x in vec]<br>[(2, 4), (4, 16), (6, 36)]<br>>>> vec1 = [2, 4, 6]<br>>>> vec2 = [4, 3, -9]<br>>>> [x*y for x in vec1 for y in vec2]<br>[8, 6, -18, 16, 12, -36, 24, 18, -54]<br>>>> [x+y for x in vec1 for y in vec2]<br>[6, 5, -7, 8, 7, -5, 10, 9, -3]<br></pre> </dd> </dl> <p> </p> <h1> <br> 5.2 <tt class="keyword">del</tt> 叙述 </h1> <p> <tt class="keyword">del</tt> 叙述可以让你轻松的去掉在list当中某一个位置(index)的成员。这个叙述也可以用切割(slice)的方法来去掉某一段的成员(在之前我们必须藉着设定某个slice为空list来达成同样的效果)。请看下例: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> a<br>[-1, 1, 66.6, 333, 333, 1234.5]<br>>>> del a[0]<br>>>> a<br>[1, 66.6, 333, 333, 1234.5]<br>>>> del a[2:4]<br>>>> a<br>[1, 66.6, 1234.5]<br></pre> </dd> </dl> <p> <tt class="keyword">del</tt> 也可以用来去掉整个变数: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> del a<br></pre> </dd> </dl> <p> 如果你在去掉之后还继续使用这个变数名称的话,就会得到一个错误(除非你之后再设定另外一个值给它)。我们稍后会继续看到使用 <tt class="keyword">del</tt> 的例子。 </p> <p> </p> <h1> <br> 5.3 Tuples(固定有序列)及Sequences(有序列) </h1> <p> 我们之前所讨论的lists以及字串(strings)有很多的共通点,例如可以用index来定位置,可以切出其中的某一段(slicing)等等。事实上,list及字串都是 <i>sequence</i> 这个资料型态的特例。由于Python是一个可以不断进步的语言,其他的sequence资料型态有可能会陆续的加入。我们就来看另外一种标准的sequence资料型态:固定有序列( <i>tuple</i> )。 </p> <p> 一个tuple是由特定数目的值所组成,其成员与成员之间以逗号分开。举例如下: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> t = 12345, 54321, 'hello!'<br>>>> t[0]<br>12345<br>>>> t<br>(12345, 54321, 'hello!')<br>>>> # Tuples may be nested:<br>... u = t, (1, 2, 3, 4, 5)<br>>>> u<br>((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))<br></pre> </dd> </dl> <p> 如同在前面例子所见到的,tuples输出的结果都会包含在括弧之中。所以,巢状tuple(tuple之中有tuple)可以被清楚的区分出来。Tuple在输入的时候可以有括弧也可以没有,通常我们都会加上括弧(特别是用在在复杂的expression之中)。 </p> <p> Tuples有很多种用途,例如(x,y)座标,从资料库取出的员工的资料库记录等等。Tuples跟字串一样都是不可改变(immutable)的:我们不能单独的设定一个tuple里面的个别成员(虽然我们可以用切割及连结(concaatenation)来达到同样的效果)。我们也可以做出可以改变成员的tuple来,例如list。 </p> <p> 有一个特殊的情况就是只包含0个或1个成员的tuple:要创造这样的一个tuple,我们必须在语法上有一些的变化。空的tuple的表示方法是一对空的括弧,只有一个成员的tuple表示方法是在成员后面加上逗点(不能只是用括弧把一个成员括起来)。虽然有点奇怪,但是蛮有用的。请看例子: </p> <p> </p> <dl> <dd><pre class="verbatim">>>> empty = ()<br>>>> singleton = 'hello', # <-- note trailing comma<br>>>> len(empty)<br>0<br>>>> len(singleton)<br>1<br>>>> singleton<br>('hello',)<br></pre> </dd> </dl> <p> <code>t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -