更多高级结构

列表以及for循环

列表(list) 是Python以及其它语言中最常用到的数据结构之一。Python 使用中括号()用来解析列表,允许你以任意的顺序存储数据,从而方便处理。举例来说,如果我们需要从一个对象中抽取一些数据,我们可以将这些数据存在列表中以备后面使用:

>>> my_list = []
>>> for object in objects:
my_list.append(object.name)
>>> print (my_list)
['name_1', 'name_2', 'name_3']

上面的例子并不好,但你可以看到我们是如果从对象中提取数据,并将它们放到我们的列表中。类似的,如果我们有两个列表,使用extend方法我们可以将它们合并成一个:

>>> list_1 = [1,2,3]
>>> list_2 = [4,5,6]
>>> print (list_1.append(list_2))
[1,2,3,[4,5,6]]
>>> print (list_1.extend(list_2))
[1,2,3,4,5,6]

这能清楚地看出这两个重要方法的不同。

在我们的第一个例子中,使用到了for循环来从我们的数据中构成列表,一种更简洁的解决方法可以使用列表扩展,这可以将整个过程压缩成一行。这是Python提供的一种高效的解决方法:

>>> my_list = [object.name for object in objects]
>>> print my_list
['name_1', 'name_2', 'name_3']

再来看看这是如何映射到第一中方法的:在列表中,我们遍历objects,使用object作为从objects取出每个元素的变量名,最后我们取出object的name构成我们的列表。

除了使用方括号用来构造列表对象之外,我们还可以使用列表构造函数list()来建立我们的列表,如下:

>>> list('a')
['a']
>>> values = (1,2,3,4) # tuple object see below
>>> list(values)
[1,2,3,4]

字典

另一个普遍使用的Python数据结构是字典(Dictionaries)。字典用来存储大量数据,并且提供快速处理的方法。一种常见的字典应用的例子是通讯录系统。在字典这种数据结构中,你需要一个唯一的‘key’用来查询它对应的‘value’。在通讯录中,那个唯一的‘key’可以是电话号码,因此,字典结构是这样的:

>>> phonebook = {'012345678': 'A Person',
'987654321': 'A.N Other'}

这儿我们有一个字典,电话号码作为‘key’,对应人名作为‘value’。现在我们可以使用这个结构来查询,如下:

>>> phonebook['012345678']
'A Person'

Python的字典同样提供迭代每个数的标准方法,它们是:iteritems、iterkeys以及itervalues。这些函数分别允许我们迭代keys和values,仅迭代keys以及仅迭代values。下面是例子:

迭代所有的项:

>>> for key, value in phonebook.iteritems():
print (key, value)
987654321 A.N Other
012345678 A Person

仅迭代所有的keys:

>>> for key in phonebook.iterkeys():
print (key)
987654321
012345678
仅迭代所有的values:
>>> for value in phonebook.itervalues():
print (value)
A.N Other
A Person

与列表一样,也有不止一种创建字典的方法。到目前为止,我们只使用了逐个列举并用花括号括起来的方法来创建字典。然而,我们还可以像下面这样使用字典构造函数创建,需要传入关键字参数来创建我们字典的键值对:

>>> dict(a=1, b=2, c=3)
{'a': 1, 'c': 3, 'b': 2}
Sets 和 Frozensets

类似与列表,我们还有集合(Sets) 以及 Frozensets 的数据结构。集合允许我们像列表那样存储数据,但不同的是集合里不允许有重复元素。当我们想确保每个数据只有一份拷贝的时候,这个是非常棒的。Frozensets 几乎和普通的集合是一样的,但它是不可变的类型(immutable),这意味着一旦它被创建,它就不能再以任何方式改变。

同样,我们创建集合的方法有列举法(注意:相同的元素会自动删除):

>>> a = {1,2,3,3}
set([1, 2, 3])

也可以使用构造函数:

>>> set([1,2,3,3])
set([1, 2, 3])

Python 提供了强大的集合操作方法,我们可以完成数学中集合的并集、交集、差集等操作,如下:

>>> a = {1,2,3}
>>> b = {3,4,5}
>>> a.union(b)
set([1, 2, 3, 4, 5])
>>>
>>> a.difference(b)
set([1, 2])
>>>
>>> a.intersection(b)
set([3])

元组

最后介绍的 Python 数据类型是元组(tuples)。元组类似与列表,用逗号(,)来分隔存储的数据,与列表不同的是元组是不可变类型(immutable),列表可以任你插入或改变,而元组不行。所以,元组适用于你的数据是固定且不需改变的情形。从内存的角度来看,使用元组有一大好处是,Python可以明确地知道需要分配多少内存给元组(同样 Frozensets 也有这个好处)。

Python 同样也提供列举法和构造法来创建一个元组:

>>> my_tuple = (1,2,3,4)
(1,2,3,4)
>>>
>>> a = tuple([1,2,3,4])
>>> type(a)

关于元组这儿有几点特殊的情形需要说明。你可以使用空小括号或者使用不传参的构造函数来创建一个空的元组,但创建仅有一个元素的元组时还需要一个额外的逗号,乍一看好像是错误的,但这才是正确的语法。这是因为如果没有这个逗号,Python 会忽略小括号,仅仅只看到里面的值。下面的例子说明了这点:

>>> empty_tup = ()
>>> type(empty_tup)
>>>
>>> empty_tuple = tuple()
>>>
>>> single_tup = (1)
>>> type(single_tup)
>>>
>>> single_tup = (1,)
>>> type(single_tup)

可以看到一个小逗号作用这么大!

总结

本文主要总结了Python中我们使用的一些数据结构的不同,也罗列了一些有趣的高级的用法。