Skip to content Skip to main navigation Skip to footer

Python: 深入Python数据结构

1. Python的内置类型

在Python中,每个值都有一种数据类型,但是在使用变量时,并不像C语言那样需要声明变量的数据类型。Python根据每个变量的初始赋值情况分析其类型,并在内部对其进行跟踪。所以没有像C语言中,只定义不初始化这种情况。下面是Python中比较重要的内置数据类型:

  1. 布尔型(Booleans):值为True或为False。
  2. 数值型(Numbers):可以是整数(1、2)、浮点数(3.14)、分数(2/3),甚至为复数(2+J)。
  3. 字符串型(Strings):是Unicode字符序列。
  4. 字节与字节数组(Bytes/Byte Arrays):比如一份JPEG图像文件。
  5. 列表(List):值的有序序列。
  6. 元组(Tuples):是有序而不可变的值序列。
  7. 集合(Sets):是装满 无序值的包裹。
  8. 字典(Dictonaries):键值对的无序包裹。

当然,Python中还有更多的类型。 在Python中一切均为对象
,因此存在像模块、函数、类、方法、文件甚至已编译的代码这样的类型。

2. 与类型相关的一些函数

type()函数用来检测任何值或变量的类型。

isinstance()函数判断某个值或变量是否为给定某个类型。

int()强制int类型转换,向零取整。

float()强制float类型转换。

>>> type(range(1,10))

>>> isinstance(3.14, float)
True

Python中只有一种整数类型,即int;也只有一种浮点数类型,即float。

3. 列表

Python中的列表类型,可以容纳任何对象,而且可以随时往其中添加新的元素,它不要求所有元素属于同一类型,而不事先定义大小。它总是有办法进行动态的拓展。

3.1 列表的创建

a_list = [1, 2, 'a', 'b', ['ronny', 26]] # 包含5个元素的列表
b_list = ['one'] # 只有一个元素的列表
e_list = [] # 一个空列表

3.2 列表的访问

>>> a_list[4]
['ronny', 26]
>>> a_list[-1]
['ronny', 26]   # a_list[-n] = a_list[len(a_list) - n]

3.3 列表的切片

自左向右读取列表,第一个切片索引指明了想要的第一个元素,第二个切片索引指明了第一个不想要的元素。返回值是两者之间的任何值。

>>> a_list
[1, 2, 'a', 'b', ['ronny', 26]]
>>> a_list[1:-1]
[2, 'a', 'b', ['ronny', 26]]
>>> a_list[:3] # 不包括a_list[3]
[1, 2, 'a']
>>> a_list[3:]
[ 'b', ['ronny', 26]]
>>> a_list[:] # a_list的一份拷贝
[1, 2, 'a', 'b', ['ronny', 26]] 

3.4 列表的操作

list.append(x):把一个元素添加到链表的结尾,相当于 a[len(a):] = [x]a = a + [x]

list.append(L):把一个给定的列表中的所有元素都添加到另一个列表中,相当于 a[len(a):] = La = a + L

list.insert(i,x):在指位置拷入一个元素。 a.insert(len(a),x)相当于 a.append(x)

list.remove(x):删除链表中值为x的第一个元素。如果没有这样的元素,就会返回一个错误。

del list[a:b]:删除列表中范围a与b之间的元素。

list.pop([i]):从链表的指定位置删除元素,并将其返回。如果没有指定索引, a.pop()删除并返回最后一个元素。 []表示参数可选。

list.index(x):返回链表中第一个值为x的元素的索引。如果没有匹配的元素就会返回一个错误。

list.cout(x):返回x在链表中出现的次数。可以用来判断x是否在list中出现,不过最直接的方法是 x in list

list.sort():对链表中的元素就地进行排序,前提是链表中的元素之间可以比较大小。

list.reverse():就地倒排链表中的元素。

也许大家会发现像 insertremove或者 sort这些修改列表的方法没有打印返回值–它们返回 None。在 python 中对所有可变的数据类型这是统一的设计原则。

4. 元组

元组是元素不可变的列表。一旦创建之后,用任何方法都不可以修改元素。

4.1 元组的创建

>>> a_tuple = (1, 2, 'a', 'b', ['ronny', 26]) # 创建一个包含5个元素的元组
>>> b_tuple = (1,) # 创建只含一个元素的元组,注意逗号不能省略
>>> # 创建空元组是没有任何意义的
>>> a_tuple[4].append(1989) # 修改元组中的列表,这是合法的。
>>> a_tuple
 (1, 2, 'a', 'b', ['ronny', 25,1989])

元组和列表的主要区别是元组不能进行修改。用技术术语来说,元组是 不可变更 的。从实践的角度来说,没有可用于修改元组的方法。列表有像 append()extend()insert()remove()pop()这样的方法。这些方法,元组都没有。可以对元组进行切片操作(因为该方法创建一个新的元组),可以检查元组是否包含了特定的值(因为该操作不修改元组),还可以……就那么多了。

4.2 元组的好处

  • 元组的速度比列表更快。如果定义了一系列常量值,而所需做的仅是对它进行遍历,那么请使用元组替代列表。
  • 对不需要改变的数据进行“写保护”将使得代码更加安全。使用元组替代列表就像是有一条隐含的 assert 语句显示该数据是常量,特别的想法(及特别的功能)必须重写。
  • 一些元组可用作字典键(特别是包含字符串、数值和其它元组这样的不可变数据的元组)。列表永远不能当做字典键使用,因为列表不是不可变的。

元组可转换成列表,反之亦然。内建的 tuple()函数接受一个列表参数,并返回一个包含同样元素的元组,而 list()函数接受一个元组参数并返回一个列表。从效果上看, tuple()冻结列表,而 list()融化元组。

5. 集合

集合set有独特值的无序“袋子”。一个简单的集合可以包含任何数据类型的值。如果有两个集合,则可以执行像联合、交集以及集合求差等标准集合运算。

5.1 集合的创建

>>> a_set = {1} # 创建只包含一个元素的集合
>>> b_set = {1, 2, 'a', 'b' ,['ronny', 25]} # 创建了一个包含5个元素的集合
>>> a_set = set(a_list) # 从一个列表创建集合
>>> a_set = set() # 一个空集合
>>> a_set
set() # 此处打印的可不是{},因为它表示的是一个空字典。
>>> a_set = {} # 创建了一个空字典,而不是空集合

5.2 集合的修改

>>> a_set = {0, 1, 2}
>>> a_set.add(3) # add方法往集合中添加一个任意类型的元素,如果这个元素在集合中已经存在,则什么都不做
>>> a_set.update({4,5},[6,7],(8,9)) # update方法可以接收若干个可转换为set的参数(iterable),并求并。
>>> a_set
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> a_set.discard(10) # discard()方法接受一个单值作为参数,从集合中删除,如果该值不存在,则只是一条空指令。
>>> a_set.remove(21) # remove()方法也接受一个单值作为参数,从集合中删除,但是如果该值不存在,则引发一个KeyError例外
Traceback (most recent call last):
  File "", line 1, in 
KeyError: 21
>>> a_set.pop() # 随机从集合中删除一个值,如果集合为空,则会引发一个KeyError异常。
2
>>> a_set.clear() # 将集合清空

5.3 集合之间的运算

因为set是无序的且最多不存在相同的元素,故在tuple和list上检索的操作count和index都不能用。

>>> a_set.union(b_set) # A并B
>>> a_set.intersection(b_set) # A交B
>>> a_set.difference(b_set) # A-B,在A中不在B中
>>> a_set.symmetric_difference(b_set) # 只在A中或只在B中
>>> a.issubset(b_set) # 判断a是否为b的子集 返回布尔型
>>> a.isuperset(b_set) # 判断a是否为b的超集

6. 字典

字典是键值对的无序集合。向字典添加一个键的同时,必须为该键增添一个值。(之后可随时修改该值)

>> a_dict = {'name':'ronny', 'age':18} # 创建一个字典
>>> a_dict['sex'] = 'male' # 添加新的键值对
>>> a_dict['age'] = 26 # 修改值
>>> len(a_dict)
3
>>> a_dict['newkey'] = [1,2,3,4] # 值为一个列表

字典并非只能用于字符串。字典的值可以是任何数据类型,包括整数、布尔值、任何对象,甚至是其它的字典。而且就算在同一字典中,所有的值也无须是同一类型,您可根据需要混合匹配。字典的键要严格得多,可以是字符串、整数和其它一些类型。在同一字典中也可混合、匹配使用不同数据类型的键。

7. 其他创建方法:解析

列表解析提供了一种紧凑的方式,实现了通过对列表中每个元素应用一个函数的方法将一个列表映射到另一个列表。

>>> a_list = [1, 9 ,8 ,4]
>>> [elem*2 for elem in a_list] # 创建一个新列表而不改变原列表
[2, 18, 16, 8]

可以在列表解析中使用任何Python表达式,包含os模块中用于操作文件和目录的函数。

>>> import os, glob
>>> [os.path.realpath(f) for f in glob.glob('*.xml')]

列表解析也可以过滤列表,生成比原列表短的结果列表

>>> import os, glob
>>> [f for f in glob.glob('*.py') if os.stat(f).st_size > 6000]

到目前为止的例子中的列表解析都只是用了一些简单的表达式, 乘以一个常数、调用一个函数或者是在过滤后返回原始元素。 然而列表解析并不限制表达式的复杂程度。

>>> import os, glob
>>> [os.stat(f).st_size, os.path.realpath(f) for f in glob.glob('*.xml')]
[(3074, 'c:\\Users\\pilgrim\\diveintopython3\\examples\\feed-broken.xml'),
(3386, 'c:\\Users\\pilgrim\\diveintopython3\\examples\\feed-ns0.xml'),
(3070, 'c:\\Users\\pilgrim\\diveintopython3\\examples\\feed.xml')]

字典解析与集合解析的技巧与上面序列解析类似。

原文:http://www.cnblogs.com/ronny/p/4514228.html

0 Comments

There are no comments yet

Leave a comment

Your email address will not be published.