Python中的数据结构(Data Structures)官方详解(附代码)

Data Structures 数据结构

Python 中有四种内置数据结构 - list、tuple、dictionary 和 set。

List 列表

列表是一种数据结构,它包含项目的有序集合,即您可以在列表中存储一系列项目。如果你能想象一个购物清单,其中有一份要购买的物品清单,这很容易想象,只是你可能在购物清单中将每件物品放在单独的行上,而在 Python 中,你在它们之间放置逗号。

项目列表应括在方括号中,以便 Python 理解您正在指定列表。创建列表后,您可以在列表中添加、删除或搜索项目。由于我们可以添加和删除项目,因此我们说列表是可变数据类型,即这种类型可以更改。

对象和类快速介绍

列表是对象和类用法的一个示例。当我们使用变量 i 并为其分配一个值时,比如整数 5,你可以将其视为创建一个类(即类型)为 int 的对象(即实例)i。事实上,你可以阅读 help(int) 来更好地理解这一点。

一个类也可以具有方法,即定义为仅用于该类的函数。只有当你拥有该类的对象时,你才能使用这些功能。例如,Python 为 list 类提供了一个 append 方法,该方法允许您将项目添加到列表的末尾。例如,mylist.append(‘an item’) 会将该字符串添加到列表 mylist 中。请注意,使用点状表示法来访问对象的方法。

类也可以具有字段,这些字段只不过是定义的变量,仅用于该类。只有当你有该类的对象时,你才能使用这些变量/名称。字段也可以通过点状表示法访问,例如 mylist.field。

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

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

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

print('\nI also have to buy 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)

## **Output: 输出:**

$ python ds_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 是要去市场的人的购物清单。在 shoplist 中,我们只存储要购买的商品名称的字符串,但您可以将任何类型的对象添加到列表中,包括数字甚至其他列表。

我们也使用了…in 循环遍历列表中的项。到现在为止,您一定已经意识到列表也是一个序列。序列的特殊性将在后面的部分中讨论。

请注意,在调用 print 函数中使用了 end 参数,以指示我们希望以空格而不是通常的换行符结束输出。

接下来,我们使用 list 对象的 append 方法将项目添加到列表中,如前所述。然后,我们通过简单地将列表传递给 print 函数来打印列表的内容,从而检查该项目是否确实已添加到列表中。

然后,我们使用列表的 sort 方法对列表进行排序。重要的是要了解此方法会影响列表本身,并且不会返回修改后的列表 - 这与字符串的工作方式不同。这就是我们所说的列表是可变的,字符串是不可变的。

接下来,当我们在市场上购买完一件商品时,我们想将其从列表中删除。我们通过使用 del 语句来实现这一点。在这里,我们提到了我们要删除列表中的哪一项,而 del 语句会为我们将其从列表中删除。我们指定要从列表中删除第一项,因此我们使用 del shoplist[0](请记住,Python 从 0 开始计数)。

Tuple 元

元组用于将多个对象保存在一起。将它们视为类似于列表,但没有 list 类为您提供的广泛功能。元组的一个主要特点是它们像字符串一样是不可变的,即你不能修改元组。

元组是通过指定项目来定义的,这些项目在一对可选的括号内用逗号分隔。

元组通常用于语句或用户定义的函数可以安全地假定值集合(即使用的值元组)不会更改的情况。

zoo = ('python', 'elephant', 'penguin')
print('Number of animals in the zoo is', len(zoo))

new_zoo = 'monkey', 'camel', zoo    # parentheses not required but are a good idea
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]))
**

## Output: 输出:

**

$ python ds_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

Tuple with 0 or 1 items

具有 0 或 1 个项目的元组

空元组由一对空括号构成,例如 myempty = ()。但是,具有单个项目的 Tuples 并不那么简单。您必须在第一项(也是唯一一项)后使用逗号指定它,以便 Python 可以在表达式中区分元组和对象周围的一对括号,即,如果您的意思是您想要一个包含项 2 的元组,则必须指定 singleton = (2 , ) 。

Dictionary 字典

字典就像一个地址簿,你可以通过只知道他/她的名字来找到他的地址或联系方式,即我们将键(名称)与值(详细信息)相关联。请注意,密钥必须是唯一的,就像您有两个名字完全相同的人时无法找到正确的信息一样。

请注意,您只能将不可变对象(如字符串)用于字典的键,但可以将不可变对象或可变对象用于字典的值。这基本上就是说你应该只对键使用简单的对象。

键和值对在字典中使用表示法 d = {key1 : value1, key2 : value2 } .请注意,键值对用冒号分隔,键值对用逗号分隔,所有这些都用一对大括号括起来。

请记住,字典中的键值对不会以任何方式排序。如果您想要特定的顺序,那么您必须在使用前自行对它们进行排序。

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 {} contacts in the address-book\n'.format(len(ab)))

for name, address in ab.items():
    print('Contact {} at {}'.format(name, address))

# Adding a key-value pair
ab['Guido'] = 'guido@python.org'

if 'Guido' in ab:
    print("\nGuido's address is", ab['Guido'])
**

## Output: 输出:

**

$ python ds_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

我们使用字典的 items 方法访问字典的每个键值对,该方法返回一个元组列表,其中每个元组包含一对项目 - 键后跟值。我们检索此对,并使用 for…in 循环,然后在 for 块中打印这些值。

我们可以通过简单地使用 indexing 运算符来访问一个键并分配该值来添加新的键值对,就像我们在上述情况下对 Guido 所做的那样。

Sequence 序列

列表、元组和字符串是序列的示例,但什么是序列,它们有什么特别之处?

主要功能是成员资格测试(即 in 和 not in 表达式)和索引操作,它们允许我们直接获取序列中的特定项目。

上面提到的三种类型的序列 - 列表、元组和字符串,也有一个切片操作,它允许我们检索序列的一个切片,即序列的一部分。

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[:])
Output: 输出:

$ python ds_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

切片操作中的第一个数字(冒号之前)是指切片开始的位置,第二个数字(冒号后)表示切片的停止位置。如果未指定第一个数字,则 Python 将从序列的开头开始。如果省略第二个数字,Python 将在序列的末尾停止。请注意,返回的切片从起始位置开始,并将在结束位置之前结束,即包括起始位置,但结束位置被排除在序列切片之外。

因此,shoplist[1:3] 返回从位置 1 开始的序列切片,包括位置 2,但在位置 3 处停止,因此返回两个项目的切片。同样, shoplist[:] 返回整个序列的副本。

你也可以用负位置进行切片。负数用于序列末尾的位置。例如,shoplist[:-1] 将返回序列的一个切片,该切片不包括序列的最后一项,但包含其他所有内容。

您还可以为切片提供第三个参数,即切片的步骤(默认情况下,步长为 1):

>>> 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 等的项目。
使用 Python 解释器(即提示符)以交互方式尝试此类切片规范的各种组合,以便您可以立即看到结果。序列的伟大之处在于,你可以用同样的方式访问元组、列表和字符串!

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.intersection(bric)
{'brazil', 'india'}

References 引用

当您创建对象并将其分配给变量时,变量仅引用对象,不代表对象本身!也就是说,变量 name 指向存储对象的计算机内存部分。这称为将名称绑定到对象。

print('Simple Assignment')
shoplist = ['apple', 'mango', 'carrot', 'banana']
# mylist is just another name pointing to the same object!
mylist = shoplist

# I purchased the first item, so I remove it from the list
del shoplist[0]

print('shoplist is', shoplist)
print('mylist is', mylist)
# Notice that both shoplist and mylist both print
# the same list without the 'apple' confirming that
# they point to the same object

print('Copy by making a full slice')
# Make a copy by doing a full slice
mylist = shoplist[:]
# Remove first item
del mylist[0]

print('shoplist is', shoplist)
print('mylist is', mylist)
# Notice that now the two lists are different
Output: 输出:

$ python ds_reference.py
Simple Assignment
shoplist is ['mango', 'carrot', 'banana']
mylist is ['mango', 'carrot', 'banana']
Copy by making a full slice
shoplist is ['mango', 'carrot', 'banana']
mylist is ['carrot', 'banana']

请记住,如果要复制列表或此类序列或复杂对象(而不是整数等简单对象),则必须使用 slicing 操作来制作副本。如果你只是将变量 name 分配给另一个名称,它们都会 ‘‘引用’’ 同一个对象,如果你不小心,这可能会很麻烦。

请记住,列表的 assignment 语句不会创建副本。您必须使用 slicing 操作来复制序列。

More About Strings

你知道字符串也是对象吗,并且有方法可以做从检查字符串的一部分到去除空格的所有事情?事实上,您已经使用了 String 方法…format 方法!

您在程序中使用的字符串都是 str 类的对象。下一个例子演示了这个类的一些有用的方法。有关此类方法的完整列表,请参阅 help(str)。

# This is a string object
name = 'Swaroop'

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))
Output: 输出:

$ python ds_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 方法用于定位给定子字符串在字符串中的位置;find 如果查找子字符串失败,则返回 -1。str 类还有一个简洁的方法,用于将序列的项目与字符串连接起来,字符串充当序列每个项目之间的分隔符,并返回由此生成的更大的字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值