cari
Rumahpembangunan bahagian belakangTutorial Python[译]The Python Tutorial#Data Structures

[译]The Python Tutorial#Data Structures

5.1 Data Structures

本章节详细介绍之前介绍过的一些内容,并且也会介绍一些新的内容。

5.1 More on Lists

列表数据类型拥有更多方法,以下是列表对象的所有方法:

  • list.append(x)
    在列表末尾添加新项,等同于a[len(a):] = [x]

  • list.extend(iterable)
    添加可迭代对象中所有的项来扩展列表,等同于a[len(a):] = iterable

  • list.insert(i, x)
    在指定位置插入项。第一个参数为元素索引,新的项会在这个索引之前插入,因此a.insert(0, x)会在列表最前面插入,a.insert(len(a), x)等同于a.append(x)

  • list.remove(x)
    从列表中移除值为x的第一个项,若x不存在,方法抛出异常(ValueError异常)

  • list.pop([i])
    从列表中移除指定位置的项并返回。如果没有指定索引,a.pop()移除并返回列表中最后一个项。(方法签名中包裹i的方括号表示参数是可选的,而不是在这个位置写一个方括号。这种记号法在Python Library Reference中经常用到)

  • list.clear()
    移除列表中的所有项,等同于del a[:]

  • list.index(x[, start[, end]])
    返回第一个值为x的项的基于0的索引,如果x不存在抛出ValueError异常。
    可选参数startend被解释为切片记号法,用来将搜索限制在列表特定的子列表内。返回的索引是相对于完整列表索引,而不是相对于start参数的。

  • list.count(x)
    返回列表中x出现的次数

  • list.sort(key=None, reverse=False)
    对列表的所有项进行排序(参数用来自定义排序,参见sorted()获取更多信息)

  • list.reverse()
    反转列表元素

  • list.copy()
    返回列表的浅拷贝,等同于a[:]

以下是演示列表方法的例子:

<code class="sourceCode python"><span class="op">>>></span> fruits <span class="op">=</span> [<span class="st">'orange'</span>, <span class="st">'apple'</span>, <span class="st">'pear'</span>, <span class="st">'banana'</span>, <span class="st">'kiwi'</span>, <span class="st">'apple'</span>, <span class="st">'banana'</span>]
<span class="op">>>></span> fruits.count(<span class="st">'apple'</span>)
<span class="dv">2</span>
<span class="op">>>></span> fruits.count(<span class="st">'tangerine'</span>)
<span class="dv">0</span>
<span class="op">>>></span> fruits.index(<span class="st">'banana'</span>)
<span class="dv">3</span>
<span class="op">>>></span> fruits.index(<span class="st">'banana'</span>, <span class="dv">4</span>)  <span class="co"># Find next banana starting a position 4</span>
<span class="dv">6</span>
<span class="op">>>></span> fruits.reverse()
<span class="op">>>></span> fruits
[<span class="st">'banana'</span>, <span class="st">'apple'</span>, <span class="st">'kiwi'</span>, <span class="st">'banana'</span>, <span class="st">'pear'</span>, <span class="st">'apple'</span>, <span class="st">'orange'</span>]
<span class="op">>>></span> fruits.append(<span class="st">'grape'</span>)
<span class="op">>>></span> fruits
[<span class="st">'banana'</span>, <span class="st">'apple'</span>, <span class="st">'kiwi'</span>, <span class="st">'banana'</span>, <span class="st">'pear'</span>, <span class="st">'apple'</span>, <span class="st">'orange'</span>, <span class="st">'grape'</span>]
<span class="op">>>></span> fruits.sort()
<span class="op">>>></span> fruits
[<span class="st">'apple'</span>, <span class="st">'apple'</span>, <span class="st">'banana'</span>, <span class="st">'banana'</span>, <span class="st">'grape'</span>, <span class="st">'kiwi'</span>, <span class="st">'orange'</span>, <span class="st">'pear'</span>]
<span class="op">>>></span> fruits.pop()
<span class="co">'pear'</span></code>

诸如insert, reverse或者sort的这样,只改变了列表但是没有返回值打印,它们返回默认的None[1]。这是Python可变数据结构适用的设计原则。

5.1.1 Using Lists as Stacks

列表方法使得将其用作栈非常容易,栈中最后一个加入的元素第一个被释放(后进先出)。使用append()方法添加元素到栈顶,使用不带参数的pop()将栈顶元素出栈。示例:

<code class="sourceCode python"><span class="op">>>></span> stack <span class="op">=</span> [<span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>]
<span class="op">>>></span> stack.append(<span class="dv">6</span>)
<span class="op">>>></span> stack.append(<span class="dv">7</span>)
<span class="op">>>></span> stack
[<span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>, <span class="dv">6</span>, <span class="dv">7</span>]
<span class="op">>>></span> stack.pop()
<span class="dv">7</span>
<span class="op">>>></span> stack
[<span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>, <span class="dv">6</span>]
<span class="op">>>></span> stack.pop()
<span class="dv">6</span>
<span class="op">>>></span> stack.pop()
<span class="dv">5</span>
<span class="op">>>></span> stack
[<span class="dv">3</span>, <span class="dv">4</span>]</code>

5.1.2 Using Lists as Queues

将列表用作队列也是可能的,队列中先添加的元素先释放(先进先出);然而,这样用列表效率非常不高。因为在列表末尾添加和取出元素很快,但是在列表开头插入或者删除元素很慢(因为不得不将其他所有元素位移一位)。

经过特殊设计的collections.deque在首尾两端添加和删除元素都很快,可以使用它来实现队列。示例:

<code class="sourceCode python"><span class="op">>>></span> <span class="im">from</span> collections <span class="im">import</span> deque
<span class="op">>>></span> queue <span class="op">=</span> deque([<span class="st">"Eric"</span>, <span class="st">"John"</span>, <span class="st">"Michael"</span>])
<span class="op">>>></span> queue.append(<span class="st">"Terry"</span>)           <span class="co"># Terry arrives</span>
<span class="op">>>></span> queue.append(<span class="st">"Graham"</span>)          <span class="co"># Graham arrives</span>
<span class="op">>>></span> queue.popleft()                 <span class="co"># The first to arrive now leaves</span>
<span class="co">'Eric'</span>
<span class="op">>>></span> queue.popleft()                 <span class="co"># The second to arrive now leaves</span>
<span class="co">'John'</span>
<span class="op">>>></span> queue                           <span class="co"># Remaining queue in order of arrival</span>
deque([<span class="st">'Michael'</span>, <span class="st">'Terry'</span>, <span class="st">'Graham'</span>])</code>

5.1.3 List Comprehensions

列表推导式为创建列表提供了简洁方式。一般的应用方式是:创建新列表,列表元素是对其他序列或者可迭代对象操作的结果;或者创建元素满足特定条件的子序列。

假如希望创建一个平方列表:

<code class="sourceCode python"><span class="op">>>></span> squares <span class="op">=</span> []
<span class="op">>>></span> <span class="cf">for</span> x <span class="op">in</span> <span class="bu">range</span>(<span class="dv">10</span>):
...     squares.append(x<span class="op">**</span><span class="dv">2</span>)
...
<span class="op">>>></span> squares
[<span class="dv">0</span>, <span class="dv">1</span>, <span class="dv">4</span>, <span class="dv">9</span>, <span class="dv">16</span>, <span class="dv">25</span>, <span class="dv">36</span>, <span class="dv">49</span>, <span class="dv">64</span>, <span class="dv">81</span>]</code>

注意以上创建(或者重写)了名为x的变量,该变量在循环结束之后仍然存在。使用以下方法可创建没有任何副作用的平方列表:

<code class="sourceCode python">squares <span class="op">=</span> <span class="bu">list</span>(<span class="bu">map</span>(<span class="kw">lambda</span> x: x<span class="op">**</span><span class="dv">2</span>, <span class="bu">range</span>(<span class="dv">10</span>)))</code>

或者,等用于:

<code class="sourceCode python">squares <span class="op">=</span> [x<span class="op">**</span><span class="dv">2</span> <span class="cf">for</span> x <span class="op">in</span> <span class="bu">range</span>(<span class="dv">10</span>)]</code>

这种方式更加简洁和易读。

跟随着for子句,紧接零个或者多个for子句或者if子句的表达式再加上中括号,构成了列表推导式。其返回结果是一个新的列表,列表的元素是表达式中forif子句的计算结果。例如,以下列表推导式组合两个列表中不相等的元素:

<code class="sourceCode python"><span class="op">>>></span> [(x, y) <span class="cf">for</span> x <span class="op">in</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>] <span class="cf">for</span> y <span class="op">in</span> [<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">4</span>] <span class="cf">if</span> x <span class="op">!=</span> y]
[(<span class="dv">1</span>, <span class="dv">3</span>), (<span class="dv">1</span>, <span class="dv">4</span>), (<span class="dv">2</span>, <span class="dv">3</span>), (<span class="dv">2</span>, <span class="dv">1</span>), (<span class="dv">2</span>, <span class="dv">4</span>), (<span class="dv">3</span>, <span class="dv">1</span>), (<span class="dv">3</span>, <span class="dv">4</span>)]</code>

等价于:

<code class="sourceCode python"><span class="op">>>></span> combs <span class="op">=</span> []
<span class="op">>>></span> <span class="cf">for</span> x <span class="op">in</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]:
...     <span class="cf">for</span> y <span class="op">in</span> [<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">4</span>]:
...         <span class="cf">if</span> x <span class="op">!=</span> y:
...             combs.append((x, y))
...
<span class="op">>>></span> combs
[(<span class="dv">1</span>, <span class="dv">3</span>), (<span class="dv">1</span>, <span class="dv">4</span>), (<span class="dv">2</span>, <span class="dv">3</span>), (<span class="dv">2</span>, <span class="dv">1</span>), (<span class="dv">2</span>, <span class="dv">4</span>), (<span class="dv">3</span>, <span class="dv">1</span>), (<span class="dv">3</span>, <span class="dv">4</span>)]</code>

注意上面两个代码段中forif语句的顺序是相同的。

如果表达式是一个元组(如上所示的(x, y)),必须将其加上括号。

<code class="sourceCode python"><span class="op">>>></span> vec <span class="op">=</span> [<span class="op">-</span><span class="dv">4</span>, <span class="op">-</span><span class="dv">2</span>, <span class="dv">0</span>, <span class="dv">2</span>, <span class="dv">4</span>]
<span class="op">>>></span> <span class="co"># create a new list with the values doubled</span>
<span class="op">>>></span> [x<span class="op">*</span><span class="dv">2</span> <span class="cf">for</span> x <span class="op">in</span> vec]
[<span class="op">-</span><span class="dv">8</span>, <span class="op">-</span><span class="dv">4</span>, <span class="dv">0</span>, <span class="dv">4</span>, <span class="dv">8</span>]
<span class="op">>>></span> <span class="co"># filter the list to exclude negative numbers</span>
<span class="op">>>></span> [x <span class="cf">for</span> x <span class="op">in</span> vec <span class="cf">if</span> x <span class="op">>=</span> <span class="dv">0</span>]
[<span class="dv">0</span>, <span class="dv">2</span>, <span class="dv">4</span>]
<span class="op">>>></span> <span class="co"># apply a function to all the elements</span>
<span class="op">>>></span> [<span class="bu">abs</span>(x) <span class="cf">for</span> x <span class="op">in</span> vec]
[<span class="dv">4</span>, <span class="dv">2</span>, <span class="dv">0</span>, <span class="dv">2</span>, <span class="dv">4</span>]
<span class="op">>>></span> <span class="co"># call a method on each element</span>
<span class="op">>>></span> freshfruit <span class="op">=</span> [<span class="st">'  banana'</span>, <span class="st">'  loganberry '</span>, <span class="st">'passion fruit  '</span>]
<span class="op">>>></span> [weapon.strip() <span class="cf">for</span> weapon <span class="op">in</span> freshfruit]
[<span class="st">'banana'</span>, <span class="st">'loganberry'</span>, <span class="st">'passion fruit'</span>]
<span class="op">>>></span> <span class="co"># create a list of 2-tuples like (number, square)</span>
<span class="op">>>></span> [(x, x<span class="op">**</span><span class="dv">2</span>) <span class="cf">for</span> x <span class="op">in</span> <span class="bu">range</span>(<span class="dv">6</span>)]
[(<span class="dv">0</span>, <span class="dv">0</span>), (<span class="dv">1</span>, <span class="dv">1</span>), (<span class="dv">2</span>, <span class="dv">4</span>), (<span class="dv">3</span>, <span class="dv">9</span>), (<span class="dv">4</span>, <span class="dv">16</span>), (<span class="dv">5</span>, <span class="dv">25</span>)]
<span class="op">>>></span> <span class="co"># the tuple must be parenthesized, otherwise an error is raised</span>
<span class="op">>>></span> [x, x<span class="op">**</span><span class="dv">2</span> <span class="cf">for</span> x <span class="op">in</span> <span class="bu">range</span>(<span class="dv">6</span>)]
  File <span class="st">"<stdin>"</span>, line <span class="dv">1</span>, <span class="op">in</span> <span class="op"><</span>module<span class="op">></span>
    [x, x<span class="op">**</span><span class="dv">2</span> <span class="cf">for</span> x <span class="op">in</span> <span class="bu">range</span>(<span class="dv">6</span>)]
               <span class="op">^</span>
<span class="pp">SyntaxError</span>: invalid syntax
<span class="op">>>></span> <span class="co"># flatten a list using a listcomp with two 'for'</span>
<span class="op">>>></span> vec <span class="op">=</span> [[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>], [<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>], [<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>]]
<span class="op">>>></span> [num <span class="cf">for</span> elem <span class="op">in</span> vec <span class="cf">for</span> num <span class="op">in</span> elem]
[<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>, <span class="dv">6</span>, <span class="dv">7</span>, <span class="dv">8</span>, <span class="dv">9</span>]</code>

列表推导式可以包含复杂的表达式甚至嵌套函数:

<code class="sourceCode python"><span class="op">>>></span> <span class="im">from</span> math <span class="im">import</span> pi
<span class="op">>>></span> [<span class="bu">str</span>(<span class="bu">round</span>(pi, i)) <span class="cf">for</span> i <span class="op">in</span> <span class="bu">range</span>(<span class="dv">1</span>, <span class="dv">6</span>)]
[<span class="st">'3.1'</span>, <span class="st">'3.14'</span>, <span class="st">'3.142'</span>, <span class="st">'3.1416'</span>, <span class="st">'3.14159'</span>]</code>

5.1.4 Nested List Comprehensions

列表推导式开头的表达式可以是任意表达式,包括另一个列表推导式。

考虑以下示例,一个包含3个长度为4的列表的列表实现了3x4的矩阵:

<code class="sourceCode python">matrix <span class="op">=</span> [
    [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>],
    [<span class="dv">5</span>, <span class="dv">6</span>, <span class="dv">7</span>, <span class="dv">8</span>],
    [<span class="dv">9</span>, <span class="dv">10</span>, <span class="dv">11</span>, <span class="dv">12</span>],
]</code>

以下列表推导式反转行列:

<code class="sourceCode python"><span class="op">>>></span> [[row[i] <span class="cf">for</span> row <span class="op">in</span> matrix] <span class="cf">for</span> i <span class="op">in</span> <span class="bu">range</span>(<span class="dv">4</span>)]
[[<span class="dv">1</span>, <span class="dv">5</span>, <span class="dv">9</span>], [<span class="dv">2</span>, <span class="dv">6</span>, <span class="dv">10</span>], [<span class="dv">3</span>, <span class="dv">7</span>, <span class="dv">11</span>], [<span class="dv">4</span>, <span class="dv">8</span>, <span class="dv">12</span>]]</code>

前面的章节提到,嵌套的列表推导式是在其后跟随的for的上下文中求值的,因此这个示例等同于:

<code class="sourceCode python"><span class="op">>>></span> transposed <span class="op">=</span> []
<span class="op">>>></span> <span class="cf">for</span> i <span class="op">in</span> <span class="bu">range</span>(<span class="dv">4</span>):
...     transposed.append([row[i] <span class="cf">for</span> row <span class="op">in</span> matrix])
...
<span class="op">>>></span> transposed
[[<span class="dv">1</span>, <span class="dv">5</span>, <span class="dv">9</span>], [<span class="dv">2</span>, <span class="dv">6</span>, <span class="dv">10</span>], [<span class="dv">3</span>, <span class="dv">7</span>, <span class="dv">11</span>], [<span class="dv">4</span>, <span class="dv">8</span>, <span class="dv">12</span>]]</code>

依次等同于:

<code class="sourceCode python"><span class="op">>>></span> transposed <span class="op">=</span> []
<span class="op">>>></span> <span class="cf">for</span> i <span class="op">in</span> <span class="bu">range</span>(<span class="dv">4</span>):
...     <span class="co"># the following 3 lines implement the nested listcomp</span>
...     transposed_row <span class="op">=</span> []
...     <span class="cf">for</span> row <span class="op">in</span> matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
<span class="op">>>></span> transposed
[[<span class="dv">1</span>, <span class="dv">5</span>, <span class="dv">9</span>], [<span class="dv">2</span>, <span class="dv">6</span>, <span class="dv">10</span>], [<span class="dv">3</span>, <span class="dv">7</span>, <span class="dv">11</span>], [<span class="dv">4</span>, <span class="dv">8</span>, <span class="dv">12</span>]]</code>

在实践中,应该选择built-in函数来复合流程语句。在以上的用例中zip()函数更有用:

<code class="sourceCode python"><span class="op">>>></span> <span class="bu">list</span>(<span class="bu">zip</span>(<span class="op">*</span>matrix))
[(<span class="dv">1</span>, <span class="dv">5</span>, <span class="dv">9</span>), (<span class="dv">2</span>, <span class="dv">6</span>, <span class="dv">10</span>), (<span class="dv">3</span>, <span class="dv">7</span>, <span class="dv">11</span>), (<span class="dv">4</span>, <span class="dv">8</span>, <span class="dv">12</span>)]</code>

参见 Unpacking Argument Lists了解关于上面*使用的更多详细信息。

5.2 The del statement

在提供列表索引而不是值的情况下,有一种方法可以移除列表中的元素:del语句。这种方式与返回值的pop()方法不同。del语句也可以用来移除部分列表或者清除整个列表(之前使用将空的列表赋值给列表片段的方式实现)。示例:

<code class="sourceCode python"><span class="op">>>></span> a <span class="op">=</span> [<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>, <span class="fl">66.25</span>, <span class="dv">333</span>, <span class="dv">333</span>, <span class="fl">1234.5</span>]
<span class="op">>>></span> <span class="kw">del</span> a[<span class="dv">0</span>]
<span class="op">>>></span> a
[<span class="dv">1</span>, <span class="fl">66.25</span>, <span class="dv">333</span>, <span class="dv">333</span>, <span class="fl">1234.5</span>]
<span class="op">>>></span> <span class="kw">del</span> a[<span class="dv">2</span>:<span class="dv">4</span>]
<span class="op">>>></span> a
[<span class="dv">1</span>, <span class="fl">66.25</span>, <span class="fl">1234.5</span>]
<span class="op">>>></span> <span class="kw">del</span> a[:]
<span class="op">>>></span> a
[]</code>

del也可以用来删除整个变量:

<code class="sourceCode python"><span class="op">>>></span> <span class="kw">del</span> a</code>

此后引用名字a会抛出异常(至少在其他值赋值给名字a之前)。接下来会有更多del的使用

5.3 Tuples and Sequences

列表和字符串有很多常用属性,比如索引和切片操作。它们是序列数据类型(参见 Sequence Types - list, tuple, range)的两种。Python是一种不断进化的语言,其他的序列类型也可以加入。元组是另一种标准的序列数据类型。

元组包含若干由逗号分隔的值,示例:

<code class="sourceCode python"><span class="op">>>></span> t <span class="op">=</span> <span class="dv">12345</span>, <span class="dv">54321</span>, <span class="st">'hello!'</span>
<span class="op">>>></span> t[<span class="dv">0</span>]
<span class="dv">12345</span>
<span class="op">>>></span> t
(<span class="dv">12345</span>, <span class="dv">54321</span>, <span class="st">'hello!'</span>)
<span class="op">>>></span> <span class="co"># Tuples may be nested:</span>
... u <span class="op">=</span> t, (<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>)
<span class="op">>>></span> u
((<span class="dv">12345</span>, <span class="dv">54321</span>, <span class="st">'hello!'</span>), (<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>))
<span class="op">>>></span> <span class="co"># Tuples are immutable:</span>
... t[<span class="dv">0</span>] <span class="op">=</span> <span class="dv">88888</span>
Traceback (most recent call last):
  File <span class="st">"<stdin>"</span>, line <span class="dv">1</span>, <span class="op">in</span> <span class="op"><</span>module<span class="op">></span>
<span class="pp">TypeError</span>: <span class="st">'tuple'</span> <span class="bu">object</span> does <span class="op">not</span> support item assignment
<span class="op">>>></span> <span class="co"># but they can contain mutable objects:</span>
... v <span class="op">=</span> ([<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>], [<span class="dv">3</span>, <span class="dv">2</span>, <span class="dv">1</span>])
<span class="op">>>></span> v
([<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>], [<span class="dv">3</span>, <span class="dv">2</span>, <span class="dv">1</span>])</code>

可见,输出的元组总是放在圆括号中,以便于嵌套的元组可以被正确解析;虽然圆括号总是必须的(如果元组是其他更大表达式的一部分),但是在输入元组的时候可以选择使用圆括号。不能对元组的单个项赋值,但是可以创建包含如列表的可变对象的元组。

虽然元组和列表有些相似,但是他们通常以不同的目的,用于不同的场景。元组是不可变的,通常包含不同类型的元素,可以通过拆包操作(参见后续章节)或者索引(或者当元组是命名元组时,甚至可以通过属性来访问)来访问。列表是可变的,通常其元素也是不同类型的,可以通过对列表的迭代访问元素。

构建包含零个或者1个项的元组比较特殊:一种额外的奇怪语法可以适用于这种情况。空元组由一对空的圆括号创建;一个元素的元组由一个跟着逗号的值创建(在圆括号中放入单个值是不够的。译注:这种情况:(1)表示整数而不是元组,使用(1, )表示元组也是可行的)。丑陋但是有效。示例:

<code class="sourceCode python"><span class="op">>>></span> empty <span class="op">=</span> ()
<span class="op">>>></span> singleton <span class="op">=</span> <span class="st">'hello'</span>,    <span class="co"># <-- note trailing comma</span>
<span class="op">>>></span> <span class="bu">len</span>(empty)
<span class="dv">0</span>
<span class="op">>>></span> <span class="bu">len</span>(singleton)
<span class="dv">1</span>
<span class="op">>>></span> singleton
(<span class="st">'hello'</span>,)</code>

语句t = 12345, 54321, 'hello!'是封装元组的一个示例:值12345, 54321hello!被封装到了一个元组中。逆向操作也是可行的:

<code class="sourceCode python"><span class="op">>>></span> x, y, z <span class="op">=</span> t</code>

非常恰当地称之为序列解包,适用于任何在等号右边的序列(译注:等号右操作数)。序列解包要求等号左边待赋值的变量数量与序列包含元素数目相同。注意多重赋值只是封装元组和序列解包的结合(译注:多重赋值:i, j = 1, 2

5.4 Set

Python也包含实现了集合的数据类型。集合是无序不重复的元素集。基本功能包括成员关系测试和重复实体消除。集合对象也支持并集,交集,差集以及对称差集等数学操作。

可以使用花括号和set()函数创建集合。谨记:创建空集合必须使用set函数,不能使用{},后者用于创建空字典。

以下是简单示范:

<code class="sourceCode python"><span class="op">>>></span> basket <span class="op">=</span> {<span class="st">'apple'</span>, <span class="st">'orange'</span>, <span class="st">'apple'</span>, <span class="st">'pear'</span>, <span class="st">'orange'</span>, <span class="st">'banana'</span>}
<span class="op">>>></span> <span class="bu">print</span>(basket)                      <span class="co"># show that duplicates have been removed</span>
{<span class="st">'orange'</span>, <span class="st">'banana'</span>, <span class="st">'pear'</span>, <span class="st">'apple'</span>}
<span class="op">>>></span> <span class="st">'orange'</span> <span class="op">in</span> basket                 <span class="co"># fast membership testing</span>
<span class="va">True</span>
<span class="op">>>></span> <span class="st">'crabgrass'</span> <span class="op">in</span> basket
<span class="va">False</span>

<span class="op">>>></span> <span class="co"># Demonstrate set operations on unique letters from two words</span>
...
<span class="op">>>></span> a <span class="op">=</span> <span class="bu">set</span>(<span class="st">'abracadabra'</span>)
<span class="op">>>></span> b <span class="op">=</span> <span class="bu">set</span>(<span class="st">'alacazam'</span>)
<span class="op">>>></span> a                                  <span class="co"># unique letters in a</span>
{<span class="st">'a'</span>, <span class="st">'r'</span>, <span class="st">'b'</span>, <span class="st">'c'</span>, <span class="st">'d'</span>}
<span class="op">>>></span> a <span class="op">-</span> b                              <span class="co"># letters in a but not in b</span>
{<span class="st">'r'</span>, <span class="st">'d'</span>, <span class="st">'b'</span>}
<span class="op">>>></span> a <span class="op">|</span> b                              <span class="co"># letters in a or b or both</span>
{<span class="st">'a'</span>, <span class="st">'c'</span>, <span class="st">'r'</span>, <span class="st">'d'</span>, <span class="st">'b'</span>, <span class="st">'m'</span>, <span class="st">'z'</span>, <span class="st">'l'</span>}
<span class="op">>>></span> a <span class="op">&</span> b                              <span class="co"># letters in both a and b</span>
{<span class="st">'a'</span>, <span class="st">'c'</span>}
<span class="op">>>></span> a <span class="op">^</span> b                              <span class="co"># letters in a or b but not both</span>
{<span class="st">'r'</span>, <span class="st">'d'</span>, <span class="st">'b'</span>, <span class="st">'m'</span>, <span class="st">'z'</span>, <span class="st">'l'</span>}</code>

与列表推导式相同,Python也支持集合推导式:

<code class="sourceCode python"><span class="op">>>></span> a <span class="op">=</span> {x <span class="cf">for</span> x <span class="op">in</span> <span class="st">'abracadabra'</span> <span class="cf">if</span> x <span class="op">not</span> <span class="op">in</span> <span class="st">'abc'</span>}
<span class="op">>>></span> a
{<span class="st">'r'</span>, <span class="st">'d'</span>}</code>

5.5 Dictionaries

另一个内嵌入Python中的数据结构是字典(参见 Mapping Types - dict)。字典在其他一些语言中被称为“联合存储”或者“联合数组”。与序列不同,序列以一系列数字作索引,字典以作索引,键可以是任何不可变类型;通常使用字符串和数字作为键。只包含字符串,数字或者其他元组的元组也可以作为键;直接或者间接包含可变对象的元组不能作为键。因为列表可以使用索引赋值,切片赋值或者append()以及extend()等方法改变自身,所以列表不能作为键。

最好的理解字典的方式是将其认为是键值对的无序集合,同一集合中键唯一。一对花括号创建空字典:{}。在花括号中放置由逗号分隔键值对列表可以为字典添加初始键值对;这也是字典输出的格式。

字典提供的主要操作是:使用键存储值以及取值。可以使用del删除一个键值对。如果使用已经存在的键来存储值,那么与键关联的旧值会被重写。使用不存在的键来取值会抛出异常。

在字典上执行list(d.keys())返回字典所有键的无序列表(使用sorted(d.keys())使其有序)[2]。使用关键字in检查键在字典中是否存在。

以下是使用字典的示例:

<code class="sourceCode python"><span class="op">>>></span> tel <span class="op">=</span> {<span class="st">'jack'</span>: <span class="dv">4098</span>, <span class="st">'sape'</span>: <span class="dv">4139</span>}
<span class="op">>>></span> tel[<span class="st">'guido'</span>] <span class="op">=</span> <span class="dv">4127</span>
<span class="op">>>></span> tel
{<span class="st">'sape'</span>: <span class="dv">4139</span>, <span class="st">'guido'</span>: <span class="dv">4127</span>, <span class="st">'jack'</span>: <span class="dv">4098</span>}
<span class="op">>>></span> tel[<span class="st">'jack'</span>]
<span class="dv">4098</span>
<span class="op">>>></span> <span class="kw">del</span> tel[<span class="st">'sape'</span>]
<span class="op">>>></span> tel[<span class="st">'irv'</span>] <span class="op">=</span> <span class="dv">4127</span>
<span class="op">>>></span> tel
{<span class="st">'guido'</span>: <span class="dv">4127</span>, <span class="st">'irv'</span>: <span class="dv">4127</span>, <span class="st">'jack'</span>: <span class="dv">4098</span>}
<span class="op">>>></span> <span class="bu">list</span>(tel.keys())
[<span class="st">'irv'</span>, <span class="st">'guido'</span>, <span class="st">'jack'</span>]
<span class="op">>>></span> <span class="bu">sorted</span>(tel.keys())
[<span class="st">'guido'</span>, <span class="st">'irv'</span>, <span class="st">'jack'</span>]
<span class="op">>>></span> <span class="st">'guido'</span> <span class="op">in</span> tel
<span class="va">True</span>
<span class="op">>>></span> <span class="st">'jack'</span> <span class="op">not</span> <span class="op">in</span> tel
<span class="va">False</span></code>

dict()构造器直接使用键值对序列构造字典:

<code class="sourceCode python"><span class="op">>>></span> <span class="bu">dict</span>([(<span class="st">'sape'</span>, <span class="dv">4139</span>), (<span class="st">'guido'</span>, <span class="dv">4127</span>), (<span class="st">'jack'</span>, <span class="dv">4098</span>)])
{<span class="st">'sape'</span>: <span class="dv">4139</span>, <span class="st">'jack'</span>: <span class="dv">4098</span>, <span class="st">'guido'</span>: <span class="dv">4127</span>}</code>

此外,字典推导式可以从任意键值表达式中创建字典:

<code class="sourceCode python"><span class="op">>>></span> {x: x<span class="op">**</span><span class="dv">2</span> <span class="cf">for</span> x <span class="op">in</span> (<span class="dv">2</span>, <span class="dv">4</span>, <span class="dv">6</span>)}
{<span class="dv">2</span>: <span class="dv">4</span>, <span class="dv">4</span>: <span class="dv">16</span>, <span class="dv">6</span>: <span class="dv">36</span>}</code>

当键是简单的字符串时,可以使用关键字参数来指定键值对:

<code class="sourceCode python"><span class="op">>>></span> <span class="bu">dict</span>(sape<span class="op">=</span><span class="dv">4139</span>, guido<span class="op">=</span><span class="dv">4127</span>, jack<span class="op">=</span><span class="dv">4098</span>)
{<span class="st">'sape'</span>: <span class="dv">4139</span>, <span class="st">'jack'</span>: <span class="dv">4098</span>, <span class="st">'guido'</span>: <span class="dv">4127</span>}</code>

5.6 Looping Techniques

遍历字典时,使用items()方法可以同时检索键及其对应的值。

<code class="sourceCode python"><span class="op">>>></span> knights <span class="op">=</span> {<span class="st">'gallahad'</span>: <span class="st">'the pure'</span>, <span class="st">'robin'</span>: <span class="st">'the brave'</span>}
<span class="op">>>></span> <span class="cf">for</span> k, v <span class="op">in</span> knights.items():
...     <span class="bu">print</span>(k, v)
...
gallahad the pure
robin the brave</code>

遍历序列时,使用enumerate()函数可以同时检索位置索引及其对应的值:

<code class="sourceCode python"><span class="op">>>></span> <span class="cf">for</span> i, v <span class="op">in</span> <span class="bu">enumerate</span>([<span class="st">'tic'</span>, <span class="st">'tac'</span>, <span class="st">'toe'</span>]):
...     <span class="bu">print</span>(i, v)
...
<span class="dv">0</span> tic
<span class="dv">1</span> tac
<span class="dv">2</span> toe</code>

同时遍历两个或者更多序列时,使用zip()函数可以将元素组成对:

<code class="sourceCode python"><span class="op">>>></span> questions <span class="op">=</span> [<span class="st">'name'</span>, <span class="st">'quest'</span>, <span class="st">'favorite color'</span>]
<span class="op">>>></span> answers <span class="op">=</span> [<span class="st">'lancelot'</span>, <span class="st">'the holy grail'</span>, <span class="st">'blue'</span>]
<span class="op">>>></span> <span class="cf">for</span> q, a <span class="op">in</span> <span class="bu">zip</span>(questions, answers):
...     <span class="bu">print</span>(<span class="st">'What is your </span><span class="sc">{0}</span><span class="st">?  It is </span><span class="sc">{1}</span><span class="st">.'</span>.<span class="bu">format</span>(q, a))
...
What <span class="op">is</span> your name?  It <span class="op">is</span> lancelot.
What <span class="op">is</span> your quest?  It <span class="op">is</span> the holy grail.
What <span class="op">is</span> your favorite color?  It <span class="op">is</span> blue.</code>

需要逆序遍历序列时,首先指定一个正向的序列,然后调用reversed()函数:

<code class="sourceCode python"><span class="op">>>></span> <span class="cf">for</span> i <span class="op">in</span> <span class="bu">reversed</span>(<span class="bu">range</span>(<span class="dv">1</span>, <span class="dv">10</span>, <span class="dv">2</span>)):
...     <span class="bu">print</span>(i)
...
<span class="dv">9</span>
<span class="dv">7</span>
<span class="dv">5</span>
<span class="dv">3</span>
<span class="dv">1</span></code>

需要以特定顺序遍历序列时,使用sorted()函数返回新的有序序列,原序列不会改动:

<code class="sourceCode python"><span class="op">>>></span> basket <span class="op">=</span> [<span class="st">'apple'</span>, <span class="st">'orange'</span>, <span class="st">'apple'</span>, <span class="st">'pear'</span>, <span class="st">'orange'</span>, <span class="st">'banana'</span>]
<span class="op">>>></span> <span class="cf">for</span> f <span class="op">in</span> <span class="bu">sorted</span>(<span class="bu">set</span>(basket)):
...     <span class="bu">print</span>(f)
...
apple
banana
orange
pear</code>

有时需要在遍历序列的同时修改序列,创建新的替代序列更加简单并且安全:

<code class="sourceCode python"><span class="op">>>></span> <span class="im">import</span> math
<span class="op">>>></span> raw_data <span class="op">=</span> [<span class="fl">56.2</span>, <span class="bu">float</span>(<span class="st">'NaN'</span>), <span class="fl">51.7</span>, <span class="fl">55.3</span>, <span class="fl">52.5</span>, <span class="bu">float</span>(<span class="st">'NaN'</span>), <span class="fl">47.8</span>]
<span class="op">>>></span> filtered_data <span class="op">=</span> []
<span class="op">>>></span> <span class="cf">for</span> value <span class="op">in</span> raw_data:
...     <span class="cf">if</span> <span class="op">not</span> math.isnan(value):
...         filtered_data.append(value)
...
<span class="op">>>></span> filtered_data
[<span class="fl">56.2</span>, <span class="fl">51.7</span>, <span class="fl">55.3</span>, <span class="fl">52.5</span>, <span class="fl">47.8</span>]</code>

5.7 More on Conditions

whileif语句中使用的条件可以包含任意操作符,不仅仅是比较运算符。

比较运算符innot in检查指定值在序列中是否存在(不存在)。操作符isis not比较两个对象是否真正相同(内存地址比较);这两个操作符只对像列表那样的可变对象重要。所有的比较运算符拥有相同的优先级,并且都低于数字运算符。

比较运算符可以链接起来。例如a 993af384686a29f1363ddcc82582135e比较不同类型的对象是合法的。例如,混合数字类型之间的比较是根据其数字上的值,0等于0.0。否则,解释器会抛出TypeException异常,而不是随意提供结果

Footnotes

[1] 其他语言可能返回改变后的对象,从而允许方法链接,如:d->insert("a")>remove("b")->sort();
[2] 调用d.keys()返回一个dictionary view对象。从而支持如成员关系测试和迭代之类的操作,但是其内容并不是独立于原始字典的,只是一个视图

Atas ialah kandungan terperinci [译]The Python Tutorial#Data Structures. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Python vs C: Lengkung pembelajaran dan kemudahan penggunaanPython vs C: Lengkung pembelajaran dan kemudahan penggunaanApr 19, 2025 am 12:20 AM

Python lebih mudah dipelajari dan digunakan, manakala C lebih kuat tetapi kompleks. 1. Sintaks Python adalah ringkas dan sesuai untuk pemula. Penaipan dinamik dan pengurusan memori automatik menjadikannya mudah digunakan, tetapi boleh menyebabkan kesilapan runtime. 2.C menyediakan kawalan peringkat rendah dan ciri-ciri canggih, sesuai untuk aplikasi berprestasi tinggi, tetapi mempunyai ambang pembelajaran yang tinggi dan memerlukan memori manual dan pengurusan keselamatan jenis.

Python vs C: Pengurusan dan Kawalan MemoriPython vs C: Pengurusan dan Kawalan MemoriApr 19, 2025 am 12:17 AM

Python dan C mempunyai perbezaan yang signifikan dalam pengurusan dan kawalan memori. 1. Python menggunakan pengurusan memori automatik, berdasarkan pengiraan rujukan dan pengumpulan sampah, memudahkan kerja pengaturcara. 2.C memerlukan pengurusan memori manual, memberikan lebih banyak kawalan tetapi meningkatkan risiko kerumitan dan kesilapan. Bahasa mana yang harus dipilih harus berdasarkan keperluan projek dan timbunan teknologi pasukan.

Python untuk pengkomputeran saintifik: rupa terperinciPython untuk pengkomputeran saintifik: rupa terperinciApr 19, 2025 am 12:15 AM

Aplikasi Python dalam pengkomputeran saintifik termasuk analisis data, pembelajaran mesin, simulasi berangka dan visualisasi. 1.Numpy menyediakan susunan pelbagai dimensi yang cekap dan fungsi matematik. 2. Scipy memanjangkan fungsi numpy dan menyediakan pengoptimuman dan alat algebra linear. 3. Pandas digunakan untuk pemprosesan dan analisis data. 4.Matplotlib digunakan untuk menghasilkan pelbagai graf dan hasil visual.

Python dan C: Mencari alat yang betulPython dan C: Mencari alat yang betulApr 19, 2025 am 12:04 AM

Sama ada untuk memilih Python atau C bergantung kepada keperluan projek: 1) Python sesuai untuk pembangunan pesat, sains data, dan skrip kerana sintaks ringkas dan perpustakaan yang kaya; 2) C sesuai untuk senario yang memerlukan prestasi tinggi dan kawalan asas, seperti pengaturcaraan sistem dan pembangunan permainan, kerana kompilasi dan pengurusan memori manualnya.

Python untuk sains data dan pembelajaran mesinPython untuk sains data dan pembelajaran mesinApr 19, 2025 am 12:02 AM

Python digunakan secara meluas dalam sains data dan pembelajaran mesin, terutamanya bergantung pada kesederhanaannya dan ekosistem perpustakaan yang kuat. 1) PANDAS digunakan untuk pemprosesan dan analisis data, 2) Numpy menyediakan pengiraan berangka yang cekap, dan 3) SCIKIT-Learn digunakan untuk pembinaan dan pengoptimuman model pembelajaran mesin, perpustakaan ini menjadikan Python alat yang ideal untuk sains data dan pembelajaran mesin.

Pembelajaran Python: Adakah 2 jam kajian harian mencukupi?Pembelajaran Python: Adakah 2 jam kajian harian mencukupi?Apr 18, 2025 am 12:22 AM

Adakah cukup untuk belajar Python selama dua jam sehari? Ia bergantung pada matlamat dan kaedah pembelajaran anda. 1) Membangunkan pelan pembelajaran yang jelas, 2) Pilih sumber dan kaedah pembelajaran yang sesuai, 3) mengamalkan dan mengkaji semula dan menyatukan amalan tangan dan mengkaji semula dan menyatukan, dan anda secara beransur-ansur boleh menguasai pengetahuan asas dan fungsi lanjutan Python dalam tempoh ini.

Python untuk Pembangunan Web: Aplikasi UtamaPython untuk Pembangunan Web: Aplikasi UtamaApr 18, 2025 am 12:20 AM

Aplikasi utama Python dalam pembangunan web termasuk penggunaan kerangka Django dan Flask, pembangunan API, analisis data dan visualisasi, pembelajaran mesin dan AI, dan pengoptimuman prestasi. 1. Rangka Kerja Django dan Flask: Django sesuai untuk perkembangan pesat aplikasi kompleks, dan Flask sesuai untuk projek kecil atau sangat disesuaikan. 2. Pembangunan API: Gunakan Flask atau DjangorestFramework untuk membina Restfulapi. 3. Analisis Data dan Visualisasi: Gunakan Python untuk memproses data dan memaparkannya melalui antara muka web. 4. Pembelajaran Mesin dan AI: Python digunakan untuk membina aplikasi web pintar. 5. Pengoptimuman Prestasi: Dioptimumkan melalui pengaturcaraan, caching dan kod tak segerak

Python vs C: Meneroka Prestasi dan KecekapanPython vs C: Meneroka Prestasi dan KecekapanApr 18, 2025 am 12:20 AM

Python lebih baik daripada C dalam kecekapan pembangunan, tetapi C lebih tinggi dalam prestasi pelaksanaan. 1. Sintaks ringkas Python dan perpustakaan yang kaya meningkatkan kecekapan pembangunan. 2. Ciri-ciri jenis kompilasi dan kawalan perkakasan meningkatkan prestasi pelaksanaan. Apabila membuat pilihan, anda perlu menimbang kelajuan pembangunan dan kecekapan pelaksanaan berdasarkan keperluan projek.

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa