python编程进阶(9):枚举、自省、推导式

枚举

枚举(enumerate)是Python内置函数。它的用处很难在简单的一行中说明,但是大多数的新人,甚至一些高级程序员都没有意识到它。

它允许我们遍历数据并自动计数,

下面是一个例子:

1
2
for counter, value in enumerate(some_list):
print(counter, value)

不只如此,enumerate也接受一些可选参数,这使它更有用。

1
2
3
4
5
6
7
8
9
10
my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 1):
print(c, value)

# 输出:
(1, 'apple')
(2, 'banana')
(3, 'grapes')
(4, 'pear')

上面这个可选参数允许我们定制从哪个数字开始枚举。
你还可以用来创建包含索引的元组列表, 例如:

1
2
3
4
my_list = ['apple', 'banana', 'grapes', 'pear']
counter_list = list(enumerate(my_list, 1))
print(counter_list)
# 输出: [(1, 'apple'), (2, 'banana'), (3, 'grapes'), (4, 'pear')]

对象自省

自省(introspection),在计算机编程领域里,是指在运行时来判断一个对象的类型的能力。它是Python的强项之一。Python中所有一切都是一个对象,而且我们可以仔细勘察那些对象。Python还包含了许多内置函数和模块来帮助我们。

dir

在这个小节里我们会学习到dir以及它在自省方面如何给我们提供便利。

它是用于自省的最重要的函数之一。它返回一个列表,列出了一个对象所拥有的属性和方法。这里是一个例子:

1
2
3
4
5
6
7
8
9
10
my_list = [1, 2, 3]
dir(my_list)
# Output: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
# '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
# '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__',
# '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__',
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
# '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',
# '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
# 'remove', 'reverse', 'sort']

上面的自省给了我们一个列表对象的所有方法的名字。当你没法回忆起一个方法的名字,这会非常有帮助。如果我们运行dir()而不传入参数,那么它会返回当前作用域的所有名字。

type和id

type函数返回一个对象的类型。举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
print(type(''))
# Output: <type 'str'>

print(type([]))
# Output: <type 'list'>

print(type({}))
# Output: <type 'dict'>

print(type(dict))
# Output: <type 'type'>

print(type(3))
# Output: <type 'int'>

id()函数返回任意不同种类对象的唯一ID内存地址,举个例子:

1
2
3
name = "Yasoob"
print(id(name))
# Output: 139972439030304

inspect模块

inspect模块也提供了许多有用的函数,来获取活跃对象的信息。比方说,你可以查看一个对象的成员,只需运行:

1
2
3
4
import inspect
print(inspect.getmembers(str))
# Output: [('__add__', <slot wrapper '__add__' of ... ...

还有好多个其他方法也能有助于自省。如果你愿意,你可以去探索它们。

inspect.ismodule(object): 是否为模块
inspect.isclass(object):是否为类
inspect.ismethod(object):是否为方法(bound method written in python)
inspect.isfunction(object):是否为函数(python function, including lambda expression)
inspect.isgeneratorfunction(object):是否为python生成器函数
inspect.isgenerator(object):是否为生成器
inspect.istraceback(object): 是否为traceback
inspect.isframe(object):是否为frame
inspect.iscode(object):是否为code
inspect.isbuiltin(object):是否为built-in函数或built-in方法
inspect.isroutine(object):是否为用户自定义或者built-in函数或方法
inspect.isabstract(object):是否为抽象基类
inspect.ismethoddescriptor(object):是否为方法标识符
inspect.isdatadescriptor(object):是否为数字标识符,数字标识符有__get____set__属性; 通常也有__name__和__doc__属性
inspect.isgetsetdescriptor(object):是否为getset descriptor
inspect.ismemberdescriptor(object):是否为member descriptor

各种推导式(comprehensions)

推导式(又称解析式)是Python的一种独有特性,如果我被迫离开了它,我会非常想念。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:

  • 列表(list)推导式
  • 字典(dict)推导式
  • 集合(set)推导式

我们将一一进行讨论。一旦你知道了使用列表推导式的诀窍,你就能轻易使用任意一种推导式了。

列表推导式(list comprehensions)

列表推导式(又称列表解析式)提供了一种简明扼要的方法来创建列表。
它的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。那个表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表,在这个以iffor语句为上下文的表达式运行完成之后产生。

规范

1
variable = [out_exp for out_exp in input_list if out_exp == 2]

字典推导式(dict comprehensions)

字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号,毕竟字典本身用的就是大括号。这里有个我最近发现的例子:

1
2
3
4
5
6
7
8
9
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}

mcase_frequency = {
k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) # 执行函数,k为每个字典的关键字
for k in mcase.keys()
}

# mcase_frequency == {'a': 17, 'z': 3, 'b': 34}

在上面的例子中我们把同一个字母但不同大小写的值合并起来了。

就我个人来说没有大量使用字典推导式。

你还可以快速对换一个字典的键和值:

1
{v: k for k, v in some_dict.items()}

集合推导式(set comprehensions)

集合推导式跟列表推导式差不多,都是对一个列表的元素全部执行相同的操作,但集合是一种无重复无序的序列
区别:跟列表推到式的区别在于:1.不使用中括号,使用大括号;2.结果中无重复;3.结果是一个set()集合,集合里面是一个序列:

1
2
3
squared = {x**2 for x in [1, 1, 2]}
print(squared)
# Output: {1, 4}
-------------Thanks for Reading!-------------