Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1798188
  • 博文数量: 335
  • 博客积分: 4690
  • 博客等级: 上校
  • 技术积分: 4341
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-08 21:38
个人简介

无聊之人--除了技术,还是技术,你懂得

文章分类

全部博文(335)

文章存档

2016年(29)

2015年(18)

2014年(7)

2013年(86)

2012年(90)

2011年(105)

分类: Python/Ruby

2011-06-16 11:01:12

4.5. Filtering Lists

列表过滤

As you know, Python has powerful capabilities for mapping lists into other lists, via list comprehensions (Section 3.6, “Mapping Lists”). This can be combined with a filtering mechanism, where some elements in the list are mapped while others are skipped entirely.

众所周知,Python拥有强大的映射列表功能来映射成其它的列表,通过列表复合操作(见3.6 映射列表)。列表映射可以同过滤机制相配合,也就是列表中的某些元素进行映射,而其它元素则完全忽略掉。

Here is the list filtering syntax:

下面是列表过滤的语法

[mapping-expression for element in source-list if filter-expression]

This is an extension of the list comprehensions that you know and love. The first two thirds are the same; the last part, starting with the if, is the filter expression. A filter expression can be any expression that evaluates true or false (which in Python can be almost anything). Any element for which the filter expression evaluates true will be included in the mapping. All other elements are ignored, so they are never put through the mapping expression and are not included in the output list.

这是你了解并喜欢的列表复合操作表达式。前面三个参数是相同的。最后一部分,以if开始,是过滤表达式。过滤表达式可以是任何可以判读得出真假的表达式(在Python中表达式可以有任何对象组成)。对列表中的任意元素,只有过滤表达式求值以后为真的元素才能映射到列表。其它的元素则被忽略,它们既不会通过映射表达式也不会被包括在输出列表中。

Example 4.14. Introducing List Filtering

4.14 列表过滤简介

  1. >>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"]
  2. >>> [elem for elem in li if len(elem) > 1]
  3. ['mpilgrim', 'foo']
  4. >>> [elem for elem in li if elem != "b"]
  5. ['a', 'mpilgrim', 'foo', 'c', 'd', 'd']
  6. >>> [elem for elem in li if li.count(elem) == 1]
  7. ['a', 'mpilgrim', 'foo', 'c']

The mapping expression here is simple (it just returns the value of each element), so concentrate on the filter expression. As Python loops through the list, it runs each element through the filter expression. If the filter expression is true, the element is mapped and the result of the mapping expression is included in the returned list. Here, you are filtering out all the one-character strings, so you're left with a list of all the longer strings.

这个映射表达式是很简单的(它仅仅是返回列表的元素值),因此将精力集中在过滤表达式上面。当Python对列表进行循环时,如果过滤表达式为真,则对应的元素被映射,映射表达式的结果包含在返回列表中。,在本例中,只是简单的过滤出所有含有一个字符的字符串,剩下的列表是由长字符串组成。

Here, you are filtering out a specific value, b. Note that this filters all occurrences of b, since each time it comes up, the filter expression will be false.

这儿,在过滤输出一个特殊值,b。注意到这个表达式过滤所有出现的b,因为每一次过滤的时候,过滤表达式的值都为假。

count is a list method that returns the number of times a value occurs in a list. You might think that this filter would eliminate duplicates from a list, returning a list containing only one copy of each value in the original list. But it doesn't, because values that appear twice in the original list (in this case, b and d) are excluded completely. There are ways of eliminating duplicates from a list, but filtering is not the solution.

Count是一个列表方法,它返回元素在列表中出现的次数。你可能会想到这个过滤器能够消除列表中重复值,返回原列表中仅含有唯一值的一个新列表。但是事实不是这样的,这是因为如果一个值在原列表中出现了两次(在本例中,b&d)被完全排除。存在其它的方法可以从列表中消除重复值,但是过滤器不是一个解决方案。

Let's get back to this line from apihelper.py:

现在返回到apihelper.py中的这行:

    methodList = [method for method in dir(object) if callable(getattr(object, method))]

This looks complicated, and it is complicated, but the basic structure is the same. The whole filter expression returns a list, which is assigned to the methodList variable. The first half of the expression is the list mapping part. The mapping expression is an identity expression, which it returns the value of each element. dir(object) returns a list ofobject's attributes and methods -- that's the list you're mapping. So the only new part is the filter expression after the if.

上面看起来非常复杂,实际上它也是非常复杂,但是最基本得结构还是相同的。整个过滤表达式返回的是列表,然后将返回列表赋值给变量methodList表达式的前半部分是列表映射。映射表达式同前面的表达式相同,它也是返回每一个元素的dir(object)方法的属性或是方法所组成的列表---正是你打算映射的列表if后面新的部分刚好是过滤表达式。

The filter expression looks scary, but it's not. You already know about callablegetattr, and in. As you saw in the previous section, the expression getattr(object, method)returns a function object if object is a module and method is the name of a function in that module.

过滤表达式看起来有点恐怖,但是不要害怕,在前面的章节,你已经对函数callable getattr和操作符in有所了解,当对象是一个模块,而方法是模块中一个函数名,getattr(object,method)表达式返回一个函数对象。

So this expression takes an object (named object). Then it gets a list of the names of the object's attributes, methods, functions, and a few other things. Then it filters that list to weed out all the stuff that you don't care about. You do the weeding out by taking the name of each attribute/method/function and getting a reference to the real thing, via thegetattr function. Then you check to see if that object is callable, which will be any methods and functions, both built-in (like the pop method of a list) and user-defined (like thebuildConnectionString function of the odbchelper module). You don't care about other attributes, like the __name__ attribute that's built in to every module.

该表达式接受一个对象(命名的object,然后就能得到对象的属性,方法,函数还有少数其它对象所组成的列表。接着对列表进行过滤,清除出你不关心的关心的元素。在进行元素删除的时候,通过getattr函数,它接受属性/方法/函数的名字,并获得上述对象的真实引用。接着判断引所指向的对象是否可以被调用,所有的方法和函数都是可以被调用的,包括内置函数(如列表的pop方法)以及用户自定义函数(模块odbchelper中的buildConnectionString函数)。现在不必关心其他属性,比如每个内置模块都有的__name__属性。

阅读(1253) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~