`
ikeycn
  • 浏览: 146234 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Python入门系列:Python内置数据结构(Data Structures)

阅读更多
Python内置数据结构(Data Strutcures)
简介:
数据结构是用来存储相关联的一组数据的集合,在Python中内置了四种数据结构,分别是list, tuple, dictionary和set。下面我们将介绍这些数据结构的基本用法。


List

list用来存储规则的(ordered)数据集合,我们可用它来存储一系列的数据元素。假设你有一个购物清单用来表示你需要买的物品,你就可以把它们存储到list中,并用"[]"包起来,元素之间使用","隔开。当你创建一个list后,你就可以添加、删除或者查找list中的元素。因为我们能够添加或者删除元素,所以list是可改变(mutable)的数据类型。
下面的代码展示了list的基本用法:
#Filename: using_list.py

# This is my shopping list
shoplist = ['apple', 'mango', 'carrot', 'banana']

print('I have ', len(shoplist), 'items to pruchase.')

print('These items are:', end=' ')

for item in shoplist:
    print(item, end=' ')

print('\nI also have to by rice.')
shoplist.append('rice')
print('My shopping list is now', shoplist)

print('I will sort my list now')
shoplist.sort()
print('Sorted shopping list is', shoplist)

print('The first item I will buy is ', shoplist[0])
olditem = shoplist[0]
del shoplist[0]
print('I bought the', olditem)
print('My shopping list is now', shoplist)

输出结果:
$ python using_list.py
I have 4 items to purchase.
These items are: apple mango carrot banana
I also have to buy rice.
My shopping list is now ['apple', 'mango', 'carrot', 'banana',
'rice']
I will sort my list now
Sorted shopping list is ['apple', 'banana', 'carrot', 'mango',
'rice']
The first item I will buy is apple
I bought the apple
My shopping list is now ['banana', 'carrot', 'mango', 'rice']

执行过程:
程序中使用shoplist来表示购物清单列表list,在shoplist中,我们用字符串存储物品的名称(当然,你可以在list中存储任何类型的数据元素)。然后我们使用for..in 循环来遍历list中的元素,现在你应该明白list其实也是一个序列(sequence)。我们将在下面看到sequence的详细介绍。
接下来,我们使用list对象的append方法向shoplist中添加新的物品元素,然后通过打印出list的所有元素来检查物品是否真的添加到list中。我们使用sort方法来对shoplist中的元素进行了排序。这里的sort方法直接影响了执行该操作的list对象,而不是返回一个新的排序后的list对象——这与string中的sort方法是不同的。这也是为什么list对象是可改变的(mutable)而string是不可改变的(immutable)。最后我们使用del方法删除list对象中的元素。
更多关于list的介绍可通过help(list)来获得。
############################################
Tuple
Tuple(数组)也是用来存储多个对象,它和list类似但tuple是不可改变的(immutable),这是与list最大的不同。tuple在定义时指定其元素,格式为('xxx', 'xxx'),其中"()"是可选的,但推荐使用"()"把元素括起来。tuple一般用在能够预知tuple的值不会被改变的地方。
下面的代码展示了tuple的简单用法:
#!/usr/bin/python
# Filename: using_tuple.py
zoo = ('python', 'elephant', 'penguin') # remember the parentheses are optional
print('Number of animals in the zoo is', len(zoo))
new_zoo = ('monkey', 'camel', zoo)
print('Number of cages in the new zoo is', len(new_zoo))
print('All animals in new zoo are', new_zoo)
print('Animals brought from old zoo are', new_zoo[2])
print('Last animal brought from old zoo is', new_zoo[2][2])
print('Number of animals in the new zoo is',
len(new_zoo)-1+len(new_zoo[2]))

输出结果:
$ python using_tuple.py
Number of animals in the zoo is 3
Number of cages in the new zoo is 3
All animals in new zoo are ('monkey', 'camel', ('python',
'elephant', 'penguin'))
Animals brought from old zoo are ('python', 'elephant', 'penguin')
Last animal brought from old zoo is penguin
Number of animals in the new zoo is 5

执行过程:
变量zoo指向了(refer to)具有若干个元素的一个tuple,我们使用len函数获得了tuple的长度(即其中元素的个数),这意味着tuple也是一种sequence。
现在我们把zoo和一些新的zoo元素保存到一个新的tuple对象new_zoo中,但我们仍然能得到对原来zoo对象的引用,因为把一个tuple嵌入到另一个tuple中并不会丢失其自身的标识。我们通过指定元素的位置([0])来访问tuple中的元素,这和list的用法是一致的。其中“[]”称为索引操作符(indexing operator)。我们可以通过new_zoo[2]来访问new_zoo中的第三个元素,也可以通过new_zoo[2][2]的方式来访问new_zoo中第三个元素的第三个元素(即嵌套tuple或者多维tuple)。
另外,可以通过指定一对空括号"()"来构造一个空的tuple,例如myempty = ()。尽管这样,仅有一个元素的tuple却不是那么简单。在tuple的仅有的一个元素后面,你必须使用","来与Python中的对象表达式相区分,因为Python中的实例化对象的表达式也是使用的"()"。例如:如果你想让一个tuple仅包含一个值为2的元素,你就必须使用这样来指定:singleton = (2,)

#####################################
Dictionary
dictionary更像是一个地址簿(或者通讯录),你能通过名称来找到他的地址或者联系方式信息,就像我们把keys(name)和values(detials)起来一样。但值得注意的是键值(key)必须是唯一的,否则如果两个人具有相同的姓名(键值)的话,我们将不能找到正确的信息。dictionary中的key只能使用不可改变(immutable),而value部分则没这个限制。这也就意味着你应该只使用简单对象类型作为key。
在Python中,使用下面的方式:d = {key1 : value1, key2 : value2}的方式来指定dictionary中的键值对。每一个键值对中用":"分隔键和值,每一对之间使用","来分隔。在最外面使用"{}"把所有键值对括起来。dictionary中的键值对(key-value pairs)之间并不以任何方式排序,如果你想指定一个规则,你必须在使用它们之间对它们进行排序。
你将要使用到的dictionary对象对象都是dict类的实例/对象(instances/objects)
下面的代码展示了dictionary的简单使用:
#!/usr/bin/python
# Filename: using_dict.py

# 'ab' is short for 'a'ddress'b'ook
ab = { 'Swaroop' : 'swaroop@swaroopch.com',
'Larry' : 'larry@wall.org',
'Matsumoto' : 'matz@ruby-lang.org',
'Spammer' : 'spammer@hotmail.com'
}
print("Swaroop's address is", ab['Swaroop'])
# Deleting a key-value pair
del ab['Spammer']
print('\nThere are {0} contacts in the address-book\n'.format(len(ab)))
for name, address in ab.items():
print('Contact {0} at {1}'.format(name, address))
# Adding a key-value pair
ab['Guido'] = 'guido@python.org'
if 'Guido' in ab: # OR ab.has_key('Guido')
print("\nGuido's address is", ab['Guido'])

输出结果:
$ python using_dict.py
Swaroop's address is swaroop@swaroopch.com
There are 3 contacts in the address-book
Contact Swaroop at swaroop@swaroopch.com
Contact Matsumoto at matz@ruby-lang.org
Contact Larry at larry@wall.org
Guido's address is guido@python.org

执行过程:
我们使用已经讨论过的方式创建了一个dictionary对象ab。然后使用索引操作符"[key]"通过指定的键值来获得具体的键值对。我们同样使用del语句对键值对(key-value pairs)进行删除操作。我们只需简单地指定dictionary对象和"[key]"就可删除key所对应的键值对。删除操作中,我们并不需要知道指定的key值对象的value。
我们通过dictionary对象的items方法获得一个数组(tuple)的list,其中每个tuple包含了items中的每一对值,('key','value')的形式。在for..in循环中我们得到每个键值对并把key和value分别赋值给了name和address,然后输出了这些值。我们也只简单地使用索引操作符"ab['key']"就可以添加新的元素到dictionary对象中。另外我们还通过in操作符或者dictionary对象的has_key方法来判断某个健值是否在给定的dictionary对象中存在。
如果想得到更多关于dictionary的信息,可通过help(dict)获得。

############################
[size=large]
Set
[/size]
set是简单对象的无序的集合。当程序中关注于对象是否存在于集合中而不是它出现的顺序或者次数时,你就可以选择使用set。使用set,你可以执行相关的集合操作,例如某个集合是否为其他集合的子集,或者找出两个不同集合的交集等等。
下面的程序给出了这些简单的应用:
>>> bri = set(['brazil', 'russia', 'india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
>>> bric = bri.copy()
>>> bric.add('china')
>>> bric.issuperset(bri)
True
>>> bri.remove('russia')
>>> bri & bric # OR bri.

执行过程:
这个例子只涉及到了数学课程中的基本集合理论,因此很容易看明白的。这里需要注意的是set对象的创建方式。创建set对象需要使用set类来显示指定,如set(['brazil', 'russia', 'india']),其参数为"[]"括起来的对象序列,对象之间使用","隔开。另外程序中使用in操作符判断元素是否存在于集合中,使用了issupperset方法来判断一个集合是否为其他集合的超集(即集合之间的包含关系),使用了&操作符得到两个集合的交集等等。
#####################################
Sequences
list, tuple和string都是sequence,但什么是sequence,它们又有什么特殊的地方呢?
它们最大的特性是具有in 或者 not in表达式用来判断某个元素是否存在于sequence和具有索引操作。索引操作(indexing operation)允许我们直接从sequence中获取指定的元素。上述的list, tuple和string也都具有另外一个slicing操作,用来从给定的sequence中获得其子sequence。
下面是关于sequence类型的示例代码:
# Filename: seq.py
shoplist = ['apple', 'mango', 'carrot', 'banana']
name = 'swaroop'
# Indexing or 'Subscription' operation
print('Item 0 is', shoplist[0])
print('Item 1 is', shoplist[1])
print('Item 2 is', shoplist[2])
print('Item 3 is', shoplist[3])
print('Item -1 is', shoplist[-1])
print('Item -2 is', shoplist[-2])
print('Character 0 is', name[0])
# Slicing on a list
print('Item 1 to 3 is', shoplist[1:3])
print('Item 2 to end is', shoplist[2:])
print('Item 1 to -1 is', shoplist[1:-1])
print('Item start to end is', shoplist[:])
# Slicing on a string
print('characters 1 to 3 is', name[1:3])
print('characters 2 to end is', name[2:])
print('characters 1 to -1 is', name[1:-1])
print('characters start to end is', name[:])

输出结果:
$ python seq.py
Item 0 is apple
Item 1 is mango
Item 2 is carrot
Item 3 is banana
Item -1 is banana
Item -2 is carrot
Character 0 is s
Item 1 to 3 is ['mango', 'carrot']
Item 2 to end is ['carrot', 'banana']
Item 1 to -1 is ['mango', 'carrot']
Item start to end is ['apple', 'mango', 'carrot', 'banana']
characters 1 to 3 is wa
characters 2 to end is aroop
characters 1 to -1 is waroo
characters start to end is swaroop

执行流程:
首先我们看到是如何通过索引获得sequence中的单个元素。它还有另外一个名字:查阅操作(subscription operation)。无论何时,你对一个sequence对象通过中括号和数字执行操作时,Python就能获得sequence相应位置上的元素。和其他主流语言一样,Python也是从0开始记数的。所以shoplist[0]获得第一个元素而shoplist[3]则获得了shoplist中的第4个元素。
Python中的索引也能是负数,这时元素的位置从sequence的末尾开始记数。所以shoplist[-1]指向了sequence的最后一个元素,shoplist[-2]得到sequence中倒数第二个元素。slicing操作通过在sequence对象后面加上中括号,及中括号中用':'隔开的数字。这与索引操作非常相似,不同的是这里的数字是可选的,并不强制需要指定。":"前的数字指子串的开始位置,":"后面的数字是子串结束的后一个位置,实际的子串并不包含该位置的元素。如果不指定第一个数字,Python将从原sequence的开始位置开始操作;如果第二个数字为空,Python将在原sequence结束位置终止。记住:子串包含开始位置位不包含结束位置。
所以,shoplist[1:3]将返回从1位置开始,包含2位置的元素但不包含第3个位置上的元素,所以返回了包含两个元素的子序列。类似的,shoplist[:]将返回原来sequence的一个拷贝。
在slicing操作中也可以使用负数。这里的负数的意义和索引操作中的意思相同,因此不做太多解释。例如:shoplist[:-1]将返回不包含最后一个元素的子sequence。
在slicing操作中也可以提供第三个数字(与第二个数字之间同样用":"隔开),这个数字代表slicing操作中的步长(默认值为1),意思是每隔一个步长的位置取元素,作为子requence的下一个位置的元素。下面代码解释了这种用法:
>>> shoplist = ['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::1]
['apple', 'mango', 'carrot', 'banana']
>>> shoplist[::2]
['apple', 'carrot']
>>> shoplist[::3]
['apple', 'banana']
>>> shoplist[::-1]
['banana', 'carrot', 'mango', 'apple']

当步长为2时,我们将获得0,2,...位置上的元素;而步长为3时,我们将得到0,3位置上的元素,依此类推。
sequence中最重要的想法是能使用相同的方式访问tuple, list和string中的元素。
##########################################
String
我们在前面已经介绍过string,还有什么需要学习的呢?在Python中,string同样被看作对象,并通过内置的操作能完成大量与string相关的操作,例如判断某字符串是否为其他子符串的子串,或者拆去字符串两端的空格等等。
在Python中,程序中使用的字符串都是str的对象。下面的例子将演示该类中的一些有用的方法,如果想了解更多的关于str的信息,可以通过help(str)获得。
# Filename: str_methods.py
name = 'Swaroop' # This is a string object
if name.startswith('Swa'):
print('Yes, the string starts with "Swa"')
if 'a' in name:
print('Yes, it contains the string "a"')
if name.find('war') != -1:
print('Yes, it contains the string "war"')
delimiter = '_*_'
mylist = ['Brazil', 'Russia', 'India', 'China']
print(delimiter.join(mylist))

输出结果:
$ python str_methods.py
Yes, the string starts with "Swa"
Yes, it contains the string "a"
Yes, it contains the string "war"
Brazil_*_Russia_*_India_*_China

执行过程:
在这段程序中,我们看到了一些string相关的方法。例如startswith用来找出某个字符串是否以给定的子符串开头;in操作用来检查一个给定的串是否是指定串的一部分;而find用来找出某字符串在给定串中出现的位置,如果不存在则返回-1。str类还有一个极及小巧的join方法,把来把sequence中的元素通过指定的连接符(delimiter)连接起来,并返回所有元素连接后形成的最长的字符串。

说明:该文章从 A byte of Python v1.92 for Python3.0翻译而来,望指正
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics