1、列表和元组
1、定义
l = [1, 2, 'hello', 'world'] # 列表中同时含有 int 和 string 类型的元素
l
[1, 2, 'hello', 'world']
tup = ('jason', 22) # 元组中同时含有 int 和 string 类型的元素
tup
('jason', 22)
2、区别
总的来说,列表和元组都是有序的,可以存储任意数据类型的集合,区别主要在于下面这两点。
- 列表是动态的,长度可变,可以随意的增加、删减或改变元素。列表的存储空间略大于元组,性能略逊于元组。
- 元组是静态的,长度大小固定,不可以对元素进行增加、删减或者改变操作。元组相对于列表更加轻量级,性能稍优,初始化速度更快。
- 如果想对已有的元组做任何"改变",那就只能重新开辟一块内存,创建新的元组了。
3、两者使用场景:
- 元素不需要改变时: 两三个元素,使用 tuple,元素多一点使用namedtuple。
- 元素需要改变时: 需要高效随机读取,使用list。需要关键字高效查找,采用 dict。去重,使用 set。大型数据节省空间,使用标准库 array。大型数据高效操作,使用 numpy.array。
2、字典和集合
1、定义
字典在 Python3.7+ 是有序的数据结构,而集合是无序的,其内部的哈希表存储结构,保证了其查找、插入、删除操作的高效性。所以,字典和集合通常运用在对元素的高效查找、去重等场景。
d1 = {'name': 'jason', 'age': 20, 'gender': 'male'}
d2 = dict({'name': 'jason', 'age': 20, 'gender': 'male'})
d3 = dict([('name', 'jason'), ('age', 20), ('gender', 'male')])
d4 = dict(name='jason', age=20, gender='male')
d1 == d2 == d3 ==d4
True
s1 = {1, 2, 3}
s2 = set([1, 2, 3])
s1 == s2
True
与列表的对比,字典和集合操作的高效性。
字典和集合为什么能够如此高效,特别是查找、插入和删除操作?
这当然和字典、集合内部的数据结构密不可分。不同于其他数据结构,字典和集合的内部结构都是一张哈希表。
- 对于字典而言,这张表存储了哈希值(hash)、键和值这 3 个元素。
- 而对集合来说,区别就是哈希表内没有键和值的配对,只有单一的元素了。
注意:集合并不支持索引操作,因为集合本质上是一个哈希表,和列表不一样。
2、思考题
# Option A
d = {'name': 'jason', 'age': 20, 'gender': 'male'}
# Option B
d = dict({'name': 'jason', 'age': 20, 'gender': 'male'})
第一种方法更快,原因是不需要去调用相关的函数,而且像 {} 应该是关键字,内部会去直接调用底层C写好的代码
# 字典的键可以是一个列表吗?下面这段代码中,字典的初始化是否正确呢?
d = {'name': 'jason', ['education']: ['Tsinghua University', 'Stanford University']}
用列表作为 Key 在这里是不被允许的,因为列表是一个动态变化的数据结构,字典当中的 key 要求是不可变的,原因也很好理解,key 首先是不重复的,如果 Key 是可以变化的话,那么随着 Key 的变化,这里就有可能就会有重复的 Key,那么这就和字典的定义相违背;如果把这里的列表换成之前我们讲过的元组是可以的,因为元组不可变
3、字符串
1、不可变
首先注意,Python 的字符串是不可变的(immutable)。
Python 中字符串的改变,通常只能通过创建新的字符串来完成。新版本 Python 中拼接操作’+='是个例外
# 把'hello'的第一个字符'h',改为大写的'H'
s = 'hello'
s[0] = 'H'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
s = 'H' + s[1:]
s = s.replace('h', 'H')
Java有可变的字符串类型,比如 StringBuilder,每次添加、改变或删除字符(串),无需创建新的字符串,时间复杂度仅为 O(1)。Python 中并没有相关的数据类型,我们还是得老老实实创建新的字符串。
2、常见操作
拼接:加法操作符,string.join(iterable)
分割:string.split(separator)
# 常常应用于对数据的解析处理,比如我们读取了某个文件的路径,想要调用数据库的 API,去读取对应的数据
def query_data(namespace, table):
"""
given namespace and table, query database to get corresponding
data
"""
path = 'hive://ads/training_table'
namespace = path.split('//')[1].split('/')[0] # 返回'ads'
table = path.split('//')[1].split('/')[1] # 返回 'training_table'
data = query_data(namespace, table)
string.strip(str),表示去掉首尾的 str 字符串;
string.lstrip(str),表示只去掉开头的 str 字符串;
string.rstrip(str),表示只去掉尾部的 str 字符串。
3、字符串格式化
print('no data available for person with id: {}, name: {}'.format(id, name))
其中的 string.format(),就是所谓的格式化函数;而大括号{}就是所谓的格式符,用来为后面的真实值——变量 name 预留位置。如果id = '123'、name='jason',那么输出便是:
'no data available for person with id: 123, name: jason'
参考文献: