更改第一章所有变量名、函数、类等文本代码

This commit is contained in:
Kevin Guan
2015-09-18 00:25:04 +08:00
parent baf3e9a302
commit bbfda16969
18 changed files with 96 additions and 96 deletions

View File

@@ -5,7 +5,7 @@
----------
问题
----------
如果一个可迭代对象的元素个数超过变量个数时,会出现"太多解压值"的异常
如果一个可迭代对象的元素个数超过变量个数时,会抛出一个 ``ValueError``
那么怎样才能从这个可迭代对象中解压出N个元素出来
|
@@ -37,8 +37,8 @@ Python的星号表达式可以用来解决这个问题。比如你在学习
>>> phone_numbers
['773-555-1212', '847-555-1212']
>>>
值得注意的是上面解压出的phone_numbers变量永远都是列表类型不管解压的电话号码数量是多少(包括0个)。
所以任何使用到phone_numbers变量的代码就不需要做多余的类型检查去确认它是否是列表类型了。
值得注意的是上面解压出的 ``phone_numbers`` 变量永远都是列表类型,不管解压的电话号码数量是多少(包括0个)。
所以,任何使用到 ``phone_numbers`` 变量的代码就不需要做多余的类型检查去确认它是否是列表类型了。
星号表达式也能用在列表的开始部分。比如你有一个公司前8个月销售数据的序列
但是你想看下最近一个月数据和前面7个月的平均值的对比。你可以这样做
@@ -108,8 +108,8 @@ Python的星号表达式可以用来解决这个问题。比如你在学习
'/usr/bin/false'
>>>
有时候,你想解压一些元素后丢弃它们,你不能简单就使用*
但是你可以使用一个普通的废弃名称,比如_或者ign
有时候,你想解压一些元素后丢弃它们,你不能简单就使用 ``*``
但是你可以使用一个普通的废弃名称,比如 ``_`` 或者 ``ign``
代码示例:

View File

@@ -41,10 +41,10 @@
----------
讨论
----------
我们在写查询元素的代码时,通常会使用包含yield表达式的生成器函数,也就是我们上面示例代码中的那样。
我们在写查询元素的代码时,通常会使用包含 ``yield`` 表达式的生成器函数,也就是我们上面示例代码中的那样。
这样可以将搜索过程代码和使用搜索结果代码解耦。如果你还不清楚什么是生成器请参看4.3节。
使用deque(maxlen=N)构造函数会新建一个固定大小的队列。当新的元素加入并且这个队列已满的时候,
使用 ``deque(maxlen=N)`` 构造函数会新建一个固定大小的队列。当新的元素加入并且这个队列已满的时候,
最老的元素会自动被移除掉。
代码示例:
@@ -66,7 +66,7 @@
尽管你也可以手动在一个列表上实现这一的操作(比如增加、删除等等)。但是这里的队列方案会更加优雅并且运行得更快些。
更一般的,deque类可以被用在任何你只需要一个简单队列数据结构的场合。
更一般的, ``deque`` 类可以被用在任何你只需要一个简单队列数据结构的场合。
如果你不设置最大队列大小,那么就会得到一个无限大小队列,你可以在队列的两端执行添加和弹出元素的操作。
代码示例:
@@ -89,5 +89,5 @@
>>> q.popleft()
4
在队列两端插入或删除元素时间复杂度都是O(1),而在列表的开头插入或删除元素的时间复杂度为O(N)
在队列两端插入或删除元素时间复杂度都是 ``O(1)`` ,而在列表的开头插入或删除元素的时间复杂度为 ``O(N)``

View File

@@ -36,7 +36,7 @@ heapq模块有两个函数``nlargest()`` 和 ``nsmallest()`` 可以完美解
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
译者注:上面代码在对每个元素进行对比的时候,会以price的值进行比较。
译者注:上面代码在对每个元素进行对比的时候,会以 ``price`` 的值进行比较。
|
@@ -55,7 +55,7 @@ heapq模块有两个函数``nlargest()`` 和 ``nsmallest()`` 可以完美解
[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]
>>>
堆数据结构最重要的特征是heap[0]永远是最小的元素。并且剩余的元素可以很容易的通过调用heapq.heappop()方法得到,
堆数据结构最重要的特征是 ``heap[0]`` 永远是最小的元素。并且剩余的元素可以很容易的通过调用 ``heapq.heappop()`` 方法得到,
该方法会先将第一个元素弹出来,然后用下一个最小的元素来取代被弹出元素(这种操作时间复杂度仅仅是O(N)N是堆大小)。
比如如果想要查找最小的3个元素你可以这样做
@@ -68,13 +68,13 @@ heapq模块有两个函数``nlargest()`` 和 ``nsmallest()`` 可以完美解
>>> heapq.heappop(nums)
2
当要查找的元素个数相对比较小的时候函数nlargest()nsmallest()是很合适的。
当要查找的元素个数相对比较小的时候,函数 ``nlargest()````nsmallest()`` 是很合适的。
如果你仅仅想查找唯一的最小或最大(N=1)的元素的话那么使用min()和max()函数会更快些。
类似的如果N的大小和集合大小接近的时候通常先排序这个集合然后再使用切片操作会更快点
(sorted(items)[:N] 或者是 sorted(items)[-N:])。
( ``sorted(items)[:N]`` 或者是 ``sorted(items)[-N:]`` )。
需要在正确场合使用函数nlargest() 和 nsmallest()才能发挥它们的优势
(如果N快接近集合大小了那么使用排序操作会更好些)。
尽管你没有必要一定使用这里的方法,但是堆数据结构的实现是一个很有趣并且值得你深入学习的东西。
基本上只要是数据结构和算法书籍里面都会有提及到。
heapq模块的官方文档里面也详细的介绍了堆数据结构底层的实现细节。
``heapq`` 模块的官方文档里面也详细的介绍了堆数据结构底层的实现细节。

View File

@@ -12,7 +12,7 @@
----------
解决方案
----------
下面的类利用heapq模块实现了一个简单的优先级队列:
下面的类利用 ``heapq`` 模块实现了一个简单的优先级队列:
.. code-block:: python
@@ -56,27 +56,27 @@
Item('grok')
>>>
仔细观察可以发现,第一个pop()操作返回优先级最高的元素。
另外注意到如果两个有着相同优先级的元素(foo 和 grok)pop操作按照它们被插入到队列的顺序返回的。
仔细观察可以发现,第一个 ``pop()`` 操作返回优先级最高的元素。
另外注意到如果两个有着相同优先级的元素( ``foo````grok`` )pop操作按照它们被插入到队列的顺序返回的。
|
----------
讨论
----------
这一小节我们主要关注heapq模块的使用。
函数 ``heapq.heappush()````heapq.heappop()`` 分别在队列_queue上插入和删除第一个元素,
这一小节我们主要关注 ``heapq`` 模块的使用。
函数 ``heapq.heappush()````heapq.heappop()`` 分别在队列 ``_queue`` 上插入和删除第一个元素,
并且队列_queue保证第一个元素拥有最小优先级(1.4节已经讨论过这个问题)。
heappop()函数总是返回"最小的"的元素这就是保证队列pop操作返回正确元素的关键。
``heappop()`` 函数总是返回"最小的"的元素这就是保证队列pop操作返回正确元素的关键。
另外由于push和pop操作时间复杂度为O(N)其中N是堆的大小因此就算是N很大的时候它们运行速度也依旧很快。
在上面代码中,队列包含了一个 ``(-priority, index, item)`` 的元组。
优先级为负数的目的是使得元素按照优先级从高到低排序。
这个跟普通的按优先级从低到高排序的堆排序恰巧相反。
index变量的作用是保证同等优先级元素的正确排序。
通过保存一个不断增加的index下标变量,可以确保元素安装它们插入的顺序排序。
而且,index变量也在相同优先级元素比较的时候起到重要作用。
``index`` 变量的作用是保证同等优先级元素的正确排序。
通过保存一个不断增加的 ``index`` 下标变量,可以确保元素安装它们插入的顺序排序。
而且, ``index`` 变量也在相同优先级元素比较的时候起到重要作用。
为了阐明这些先假定Item实例是不支持排序的
@@ -106,8 +106,8 @@ index变量的作用是保证同等优先级元素的正确排序。
TypeError: unorderable types: Item() < Item()
>>>
通过引入另外的index变量组成三元组(priority, index, item),就能很好的避免上面的错误,
因为不可能有两个元素有相同的index值。Python在做元组比较时候如果前面的比较以及可以确定结果了
通过引入另外的 ``index`` 变量组成三元组 ``(priority, index, item)`` ,就能很好的避免上面的错误,
因为不可能有两个元素有相同的 ``index`` 值。Python在做元组比较时候如果前面的比较以及可以确定结果了
后面的比较操作就不会发生了:
.. code-block:: python
@@ -124,5 +124,5 @@ index变量的作用是保证同等优先级元素的正确排序。
如果你想在多个线程中使用同一个队列,那么你需要增加适当的锁和信号量机制。
可以查看12.3小节的例子演示是怎样做的。
heapq模块的官方文档有更详细的例子程序以及对于堆理论及其实现的详细说明。
``heapq`` 模块的官方文档有更详细的例子程序以及对于堆理论及其实现的详细说明。

View File

@@ -29,8 +29,8 @@
选择使用列表还是集合取决于你的实际需求。如果你想保持元素的插入顺序就应该使用列表,
如果想去掉重复元素就使用集合(并且不关心元素的顺序问题)。
你可以很方便的使用collections模块中的defaultdict来构造这样的字典。
defaultdict的一个特征是它会自动初始化每个key刚开始对应的值,所以你只需要关注添加元素操作了。比如:
你可以很方便的使用 ``collections`` 模块中的 ``defaultdict`` 来构造这样的字典。
``defaultdict`` 的一个特征是它会自动初始化每个 ``key`` 刚开始对应的值,所以你只需要关注添加元素操作了。比如:
.. code-block:: python
@@ -46,8 +46,8 @@ defaultdict的一个特征是它会自动初始化每个key刚开始对应的值
d['a'].add(2)
d['b'].add(4)
需要注意的是defaultdict会自动为将要访问的键(就算目前字典中并不存在这样的键)创建映射实体。
如果你并不需要这样的特性你可以在一个普通的字典上使用setdefault()方法来代替。比如:
需要注意的是, ``defaultdict`` 会自动为将要访问的键(就算目前字典中并不存在这样的键)创建映射实体。
如果你并不需要这样的特性,你可以在一个普通的字典上使用 ``setdefault()`` 方法来代替。比如:
.. code-block:: python
@@ -56,7 +56,7 @@ defaultdict的一个特征是它会自动初始化每个key刚开始对应的值
d.setdefault('a', []).append(2)
d.setdefault('b', []).append(4)
但是很多程序员觉得setdefault()用起来有点别扭。因为每次调用都得创建一个新的初始值的实例(例子程序中的空列表[])。
但是很多程序员觉得 ``setdefault()`` 用起来有点别扭。因为每次调用都得创建一个新的初始值的实例(例子程序中的空列表[])。
|
@@ -74,7 +74,7 @@ defaultdict的一个特征是它会自动初始化每个key刚开始对应的值
d[key] = []
d[key].append(value)
如果使用defaultdict的话代码就更加简洁了
如果使用 ``defaultdict`` 的话代码就更加简洁了:
.. code-block:: python

View File

@@ -12,7 +12,7 @@
----------
解决方案
----------
为了能控制一个字典中元素的顺序你可以使用collections模块中的OrderedDict类。
为了能控制一个字典中元素的顺序,你可以使用 ``collections`` 模块中的 ``OrderedDict`` 类。
在迭代操作的时候它会保持元素被插入时的顺序,示例如下:
.. code-block:: python
@@ -28,8 +28,8 @@
for key in d:
print(key, d[key])
当你想要构建一个将来需要序列化或编码成其他格式的映射的时候OrderedDict是非常有用的。
比如你想精确控制以JSON编码后字段的顺序你可以先使用OrderedDict来构建这样的数据
当你想要构建一个将来需要序列化或编码成其他格式的映射的时候, ``OrderedDict`` 是非常有用的。
比如你想精确控制以JSON编码后字段的顺序你可以先使用 ``OrderedDict`` 来构建这样的数据:
.. code-block:: python
@@ -43,9 +43,9 @@
----------
讨论
----------
OrderedDict内部维护着一个根据键插入顺序排序的双向链表。每次当一个新的元素插入进来的时候
``OrderedDict`` 内部维护着一个根据键插入顺序排序的双向链表。每次当一个新的元素插入进来的时候,
它会被放到链表的尾部。对于一个已经存在的键的重复赋值不会改变键的顺序。
需要注意的是一个OrderedDict的大小是一个普通字典的两倍因为它内部维护着另外一个链表。
所以如果你要构建一个需要大量OrderedDict实例的数据结构的时候(比如读取100,000行CSV数据到一个OrderedDict列表中去)
那么你就得仔细权衡一下是否使用OrderedDict带来的好处要大过额外内存消耗的影响。
需要注意的是,一个 ``OrderedDict`` 的大小是一个普通字典的两倍,因为它内部维护着另外一个链表。
所以如果你要构建一个需要大量 ``OrderedDict`` 实例的数据结构的时候(比如读取100,000行CSV数据到一个 ``OrderedDict`` 列表中去)
那么你就得仔细权衡一下是否使用 ``OrderedDict`` 带来的好处要大过额外内存消耗的影响。

View File

@@ -24,7 +24,7 @@
'FB': 10.75
}
为了对字典值执行计算操作,通常需要使用zip()函数先将键和值反转过来。
为了对字典值执行计算操作,通常需要使用 ``zip()`` 函数先将键和值反转过来。
比如,下面是查找最小和最大股票价格和股票值的代码:
.. code-block:: python
@@ -34,7 +34,7 @@
max_price = max(zip(prices.values(), prices.keys()))
# max_price is (612.78, 'AAPL')
类似的,可以使用zip()和sorted()函数来排列字典数据:
类似的,可以使用 ``zip()````sorted()`` 函数来排列字典数据:
.. code-block:: python
@@ -43,7 +43,7 @@
# (45.23, 'ACME'), (205.55, 'IBM'),
# (612.78, 'AAPL')]
执行这些计算的时候,需要注意的是zip()函数创建的是一个只能访问一次的迭代器。
执行这些计算的时候,需要注意的是 ``zip()`` 函数创建的是一个只能访问一次的迭代器。
比如,下面的代码就会产生错误:
.. code-block:: python
@@ -65,7 +65,7 @@
max(prices) # Returns 'IBM'
这个结果并不是你想要的,因为你想要在字典的值集合上执行这些计算。
或许你会尝试着使用字典的values()方法来解决这个问题:
或许你会尝试着使用字典的 ``values()`` 方法来解决这个问题:
.. code-block:: python
@@ -75,7 +75,7 @@
不幸的是,通常这个结果同样也不是你想要的。
你可能还想要知道对应的键的信息(比如那种股票价格是最低的?)。
你可以在min()和max()函数中提供key函数参数来获取最小值或最大值对应的键的信息。比如:
你可以在 ``min()````max()`` 函数中提供 ``key`` 函数参数来获取最小值或最大值对应的键的信息。比如:
.. code-block:: python
@@ -88,12 +88,12 @@
min_value = prices[min(prices, key=lambda k: prices[k])]
前面的zip()函数方案通过将字典"反转"为(值,键)元组序列来解决了上述问题。
前面的 ``zip()`` 函数方案通过将字典"反转"为(值,键)元组序列来解决了上述问题。
当比较两个元组的时候,值会先进行比较,然后才是键。
这样的话你就能通过一条简单的语句就能很轻松的实现在字典上的求最值和排序操作了。
需要注意的是在计算操作中使用到了(值,键)对。当多个实体拥有相同的值的时候,键会决定返回结果。
比如,在执行min()和max()操作的时候,如果恰巧最小或最大值有重复的,那么拥有最小或最大键的实体会返回:
比如,在执行 ``min()````max()`` 操作的时候,如果恰巧最小或最大值有重复的,那么拥有最小或最大键的实体会返回:
.. code-block:: python

View File

@@ -28,7 +28,7 @@
'y' : 2
}
为了寻找两个字典的相同点,可以简单的在两字典的keys()或者items()方法返回结果上执行集合操作。比如:
为了寻找两个字典的相同点,可以简单的在两字典的 ``keys()`` 或者 ``items()`` 方法返回结果上执行集合操作。比如:
.. code-block:: python
@@ -55,14 +55,14 @@
讨论
----------
一个字典就是一个键集合与值集合的映射关系。
字典的keys()方法返回一个展现键集合的键视图对象。
字典的 ``keys()`` 方法返回一个展现键集合的键视图对象。
键视图的一个很少被了解的特性就是它们也支持集合操作,比如集合并、交、差运算。
所以如果你想对集合的键执行一些普通的集合操作可以直接使用键视图对象而不用先将它们转换成一个set。
字典的items()方法返回一个包含(键,值)对的元素视图对象。
字典的 ``items()`` 方法返回一个包含(键,值)对的元素视图对象。
这个对象同样也支持集合操作,并且可以被用来查找两个字典有哪些相同的键值对。
尽管字典的values()方法也是类似,但是它并不支持这里介绍的集合操作。
尽管字典的 ``values()`` 方法也是类似,但是它并不支持这里介绍的集合操作。
某种程度上是因为值视图不能保证所有的值互不相同,这样会导致某些集合操作会出现问题。
不过如果你硬要在值上面执行这些集合操作的话你可以先将值集合转换成set然后再执行集合运算就行了。

View File

@@ -12,7 +12,7 @@
----------
解决方案
----------
如果序列上的值都是hashable类型那么可以很简单的利用集合或者生成器来解决这个问题。比如
如果序列上的值都是 ``hashable`` 类型,那么可以很简单的利用集合或者生成器来解决这个问题。比如:
.. code-block:: python
@@ -30,8 +30,8 @@
>>> list(dedupe(a))
[1, 5, 2, 9, 10]
>>>
这个方法仅仅在序列中元素为hashable的时候才管用。
如果你想消除元素不可哈希(比如dict类型)的序列中重复元素的话,你需要将上述代码稍微改变一下,就像这样:
这个方法仅仅在序列中元素为 ``hashable`` 的时候才管用。
如果你想消除元素不可哈希(比如 ``dict`` 类型)的序列中重复元素的话,你需要将上述代码稍微改变一下,就像这样:
.. code-block:: python
@@ -43,7 +43,7 @@
yield item
seen.add(val)
这里的key参数指定了一个函数将序列元素转换成hashable类型。下面是它的用法示例
这里的key参数指定了一个函数将序列元素转换成 ``hashable`` 类型。下面是它的用法示例:
.. code-block:: python
@@ -82,5 +82,5 @@
for line in dedupe(f):
...
上述key函数参数模仿了sorted(),min()和max()等内置函数的相似功能。
上述key函数参数模仿了 ``sorted()`` , ``min()````max()`` 等内置函数的相似功能。
可以参考1.8和1.13小节了解更多。

View File

@@ -39,7 +39,7 @@
比如,如果你回过来看看一年前你写的代码,你会摸着脑袋想那时候自己到底想干嘛啊。
这里的解决方案是一个很简单的方法让你更加清晰的表达代码到底要做什么。
内置的slice()函数创建了一个切片对象,可以被用在任何切片允许使用的地方。比如:
内置的 ``slice()`` 函数创建了一个切片对象,可以被用在任何切片允许使用的地方。比如:
.. code-block:: python
@@ -56,22 +56,22 @@
>>> items
[0, 1, 4, 5, 6]
如果你有一个切片对象s你可以分别调用它的s.start, s.stop, s.step属性来获取更多的信息。比如:
如果你有一个切片对象s你可以分别调用它的 ``s.start`` , ``s.stop`` , ``s.step`` 属性来获取更多的信息。比如:
.. code-block:: python
>>> a = slice(5, 50, 2)
>>> a.start
>>> s = slice(5, 50, 2)
>>> s.start
5
>>> a.stop
>>> s.stop
50
>>> a.step
>>> s.step
2
>>>
另外你还能通过调用切片的indices(size)方法将它映射到一个确定大小的序列上,
这个方法返回一个三元组(start,stop,step),所有值都会被合适的缩小以满足边界限制,
从而使用的时候避免出现IndexError异常。比如
另外,你还能通过调用切片的 ``indices(size)`` 方法将它映射到一个确定大小的序列上,
这个方法返回一个三元组 ``(start, stop, step)`` ,所有值都会被合适的缩小以满足边界限制,
从而使用的时候避免出现 ``IndexError`` 异常。比如:
.. code-block:: python

View File

@@ -37,7 +37,7 @@
----------
讨论
----------
作为输入,``Counter`` 对象可以接受任意的 ``hashable`` 序列对象。
作为输入, ``Counter`` 对象可以接受任意的 ``hashable`` 序列对象。
在底层实现上,一个 ``Counter`` 对象就是一个字典,将元素映射到它出现的次数上。比如:
.. code-block:: python
@@ -60,7 +60,7 @@
9
>>>
或者你可以使用update()方法:
或者你可以使用 ``update()`` 方法:
.. code-block:: python
@@ -92,6 +92,6 @@
"you're": 1, "don't": 1, 'under': 1})
>>>
毫无疑问,``Counter`` 对象在几乎所有需要制表或者计数数据的场合是非常有用的工具。
毫无疑问, ``Counter`` 对象在几乎所有需要制表或者计数数据的场合是非常有用的工具。
在解决这类问题的时候你应该优先选择它,而不是手动的利用字典去实现。

View File

@@ -12,7 +12,7 @@
----------
解决方案
----------
通过使用operator模块的itemgetter函数可以非常容易的排序这样的数据结构。
通过使用 ``operator`` 模块的 ``itemgetter`` 函数,可以非常容易的排序这样的数据结构。
假设你从数据库中检索出来网站会员信息列表,并且以下列的数据结构返回:
.. code-block:: python
@@ -47,7 +47,7 @@
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]
itemgetter()函数也支持多个keys比如下面的代码
``itemgetter()`` 函数也支持多个keys比如下面的代码
.. code-block:: python
@@ -68,26 +68,26 @@ itemgetter()函数也支持多个keys比如下面的代码
----------
讨论
----------
在上面例子中,``rows`` 被传递给接受一个关键字参数的 ``sorted()`` 内置函数。
在上面例子中, ``rows`` 被传递给接受一个关键字参数的 ``sorted()`` 内置函数。
这个参数是 ``callable`` 类型,并且从 ``rows`` 中接受一个单一元素,然后返回被用来排序的值。
``itemgetter()`` 函数就是负责创建这个 ``callable`` 对象的。
``operator.itemgetter()`` 函数有一个被rows中的记录用来查找值的索引参数。可以是一个字典键名称
一个整形值或者任何能够传入一个对象的 ``__getitem__()`` 方法的值。
如果你传入多个索引参数给 ``itemgetter()`` ,它生成的 ``callable`` 对象会返回一个包含所有元素值的元组,
并且sorted()函数会根据这个元组中元素顺序去排序。
并且 ``sorted()`` 函数会根据这个元组中元素顺序去排序。
但你想要同时在几个字段上面进行排序(比如通过姓和名来排序,也就是例子中的那样)的时候这种方法是很有用的。
``itemgetter()`` 有时候也可以用lambda表达式代替,比如:
``itemgetter()`` 有时候也可以用 ``lambda`` 表达式代替,比如:
.. code-block:: python
rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
这种方案也不错。但是使用itemgetter()方式会运行的稍微快点。因此如果你对性能要求比较高的话就使用itemgetter()方式。
这种方案也不错。但是,使用 ``itemgetter()`` 方式会运行的稍微快点。因此,如果你对性能要求比较高的话就使用 ``itemgetter()`` 方式。
最后,不要忘了这节中展示的技术也同样适用于min()和max()等函数。比如:
最后,不要忘了这节中展示的技术也同样适用于 ``min()````max()`` 等函数。比如:
.. code-block:: python

View File

@@ -14,8 +14,8 @@
----------
内置的 ``sorted()`` 函数有一个关键字参数 ``key`` ,可以传入一个 ``callable`` 对象给它,
这个 ``callable`` 对象对每个传入的对象返回一个值,这个值会被 ``sorted`` 用来排序这些对象。
比如,如果你在应用程序里面有一个User实例序列并且你希望通过他们的user_id属性进行排序
你可以提供一个以User实例作为输入并输出对应user_id值的 ``callable`` 对象。比如:
比如,如果你在应用程序里面有一个 ``User`` 实例序列,并且你希望通过他们的 ``user_id`` 属性进行排序,
你可以提供一个以 ``User`` 实例作为输入并输出对应 ``user_id`` 值的 ``callable`` 对象。比如:
.. code-block:: python
@@ -47,9 +47,9 @@
讨论
----------
选择使用lambda函数或者是 ``attrgetter()`` 可能取决于个人喜好。
但是,``attrgetter()`` 函数通常会运行的快点,并且还能同时允许多个字段进行比较。
但是, ``attrgetter()`` 函数通常会运行的快点,并且还能同时允许多个字段进行比较。
这个跟 ``operator.itemgetter()`` 函数作用于字典类型很类似(参考1.13小节)。
例如,如果User实例还有一个first_name和last_name属性那么可以向下面这样排序
例如,如果 ``User`` 实例还有一个 ``first_name````last_name`` 属性,那么可以向下面这样排序:
.. code-block:: python

View File

@@ -5,7 +5,7 @@
----------
问题
----------
你有一个字典或者实例的序列,然后你想根据某个特定的字段比如date来分组迭代访问。
你有一个字典或者实例的序列,然后你想根据某个特定的字段比如 ``date`` 来分组迭代访问。
|
@@ -28,7 +28,7 @@
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]
现在假设你想在按date分组后的数据块上进行迭代。为了这样做你首先需要按照指定的字段(这里就是date)排序,
现在假设你想在按date分组后的数据块上进行迭代。为了这样做你首先需要按照指定的字段(这里就是 ``date`` )排序,
然后调用 ``itertools.groupby()`` 函数:
.. code-block:: python

View File

@@ -87,8 +87,8 @@
[0, 0, -5, 0, -7, 0, 0, -1]
>>>
另外一个值得关注的过滤工具就是 ``itertools.compress()``
它以一个 ``iterable`` 对象和一个相对应的Boolean选择器序列作为输入参数。
然后输出 ``iterable`` 对象中对应选择器为True的元素。
它以一个 ``iterable`` 对象和一个相对应的 ``Boolean`` 选择器序列作为输入参数。
然后输出 ``iterable`` 对象中对应选择器为 ``True`` 的元素。
当你需要用另外一个相关联的序列来过滤某个序列的时候,这个函数是非常有用的。
比如,假如现在你有下面两列数据:
@@ -106,7 +106,7 @@
]
counts = [ 0, 3, 10, 4, 1, 7, 6, 1]
现在你想将那些对应count值大于5的地址全部输出那么你可以这样做
现在你想将那些对应 ``count`` 值大于5的地址全部输出那么你可以这样做
.. code-block:: python
@@ -117,8 +117,8 @@
>>> list(compress(addresses, more5))
['5800 E 58TH', '4801 N BROADWAY', '1039 W GRANVILLE']
>>>
这里的关键点在于先创建一个Boolean序列指示哪些元素复合条件。
然后 ``compress()`` 函数根据这个序列去选择输出对应位置为True的元素。
这里的关键点在于先创建一个 ``Boolean`` 序列,指示哪些元素复合条件。
然后 ``compress()`` 函数根据这个序列去选择输出对应位置为 ``True`` 的元素。
``filter()`` 函数类似,``compress()`` 也是返回的一个迭代器。因此,如果你需要得到一个列表,
``filter()`` 函数类似, ``compress()`` 也是返回的一个迭代器。因此,如果你需要得到一个列表,
那么你需要使用 ``list()`` 来将结果转换为列表类型。

View File

@@ -31,7 +31,7 @@
'2012-10-19'
>>>
尽管namedtuple的实例看起来像一个普通的类实例但是它跟元组类型是可交换的支持所有的普通元组操作比如索引和解压。
尽管 ``namedtuple`` 的实例看起来像一个普通的类实例,但是它跟元组类型是可交换的,支持所有的普通元组操作,比如索引和解压。
比如:
.. code-block:: python

View File

@@ -20,8 +20,8 @@
a = {'x': 1, 'z': 3 }
b = {'y': 2, 'z': 4 }
现在假设你必须在两个字典中执行查找操作(比如先从a中找如果找不到再在b中找)。
一个非常简单扼解决方案就是使用collections模块中的ChainMap类。比如
现在假设你必须在两个字典中执行查找操作(比如先从 ``a`` 中找,如果找不到再在 ``b`` 中找)。
一个非常简单扼解决方案就是使用 ``collections`` 模块中的 ``ChainMap`` 类。比如:
.. code-block:: python
@@ -36,8 +36,8 @@
----------
讨论
----------
一个ChainMap接受多个字典并将它们在逻辑上变为一个字典。
然后这些字典并不是真的合并在一起了ChainMap类只是在内部创建了一个容纳这些字典的列表
一个 ``ChainMap`` 接受多个字典并将它们在逻辑上变为一个字典。
然后,这些字典并不是真的合并在一起了, ``ChainMap`` 类只是在内部创建了一个容纳这些字典的列表
并重新定义了一些常见的字典操作来遍历这个列表。大部分字典操作都是可以正常使用的,比如:
.. code-block:: python
@@ -51,7 +51,7 @@
>>>
如果出现重复键,那么第一次出现的映射值会被返回。
因此,例子程序中的c['z']总是会返回字典a中对应的值而不是b中对应的值。
因此,例子程序中的 ``c['z']`` 总是会返回字典 ``a`` 中对应的值,而不是 ``b`` 中对应的值。
对于字典的更新或删除操作总是影响的是列表中第一个字典。比如:
@@ -68,7 +68,7 @@
KeyError: "Key not found in the first mapping: 'y'"
>>>
ChainMap对于编程语言中的作用范围变量(比如globals, locals等)是非常有用的。
``ChainMap`` 对于编程语言中的作用范围变量(比如 ``globals`` , ``locals`` 等)是非常有用的。
事实上,有一些方法可以使它变得简单:
.. code-block:: python
@@ -97,7 +97,7 @@ ChainMap对于编程语言中的作用范围变量(比如globals, locals等)是
ChainMap({'x': 1})
>>>
作为ChainMap的替代你可能会考虑使用update()方法将两个字典合并。比如:
作为 ``ChainMap`` 的替代,你可能会考虑使用 ``update()`` 方法将两个字典合并。比如:
.. code-block:: python
@@ -122,7 +122,7 @@ ChainMap对于编程语言中的作用范围变量(比如globals, locals等)是
>>> merged['x']
1
ChianMap使用原来的字典它自己不创建新的字典。所以它并不会产生上面所说的结果比如
``ChianMap`` 使用原来的字典,它自己不创建新的字典。所以它并不会产生上面所说的结果,比如:
.. code-block:: python

View File

@@ -5,7 +5,7 @@
Python提供了大量的内置数据结构包括列表集合以及字典。大多数情况下使用这些数据结构式很简单的。
但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题。
因此,这一章的目的就是讨论这些比较常见的问题和算法。
另外我们也会给出在集合模块collections当中操作这些数据结构的方法。
另外,我们也会给出在集合模块 ``collections`` 当中操作这些数据结构的方法。
Contents: