从上一篇“Python入坑指北”开始,一系列的Python文章,是关于Python的学习笔记,参考书是《Python for Data Analysis, 2nd Edition》,github的仓库有详细的jupyter notebook(https://github.com/wesm/pydata-book)。
元组(tuple)
1.1 初始化
1 | # 初始化 |
以上代码输出结果:
1 | (4, 5, 6) |
可以看出几个重要的点:
- 元素以逗号“,”分割,以括号( )包含一个元组的所有元素;
- 一个tuple里面可以同时容纳多种类型的元素,且不需要声明tuple类型
- 可以使用list进行tuple的初始化;
- 可以将一个string转化为tuple;
1.2 元素访问
1 | tup1 = tuple('string') |
以上代码输出结果:
1 | s |
我们总结下访问的几个注意事项:
- 使用中括号 [ ] 进行元组元素的访问;
- 元组中元素只可读,不可写;
== ,说好的元素只读,那上面代码的第4行是怎么回事,为什么还能添加一个元素?其实tup2[1]指向的是一个list,在这里是元素指向的list不可变,list本身是可以变更的。
1.3 元组的解包 (Unpacking tuple)
1 | tup = (4, 5, 6) |
以上代码输出结果:
1 | 5 |
元组的解包可以应用到任何可迭代对象上,唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接收这些元素的元组的空档数一致;也可以用*来表示忽略多余的元素(如上代码所述);
一般的迭代对象包括:元组,列表,字典,字符串。
1.4 常用类方法
如果在ipython中或者Jupyter notebook中,使用TAB键就能列出tuple的类方法,下面说几个常用方法;
1 | tup = (1, 2, 3, 3) |
列表(list)
与tuple相比,list就是可变长的,可直接修改相应元素的对象,使用中括号 [] 进行初始化。
2.1 初始化
- 自定义初始化list
1 | a_list = [2, 3, 7, None] |
列表和元组在语法上有点类似,list可以直接从tuple初始化得到,两者之前最大的差异就是可修改与不可修改;
以上代码执行的结果如下,可以看到第5行代码修改了list的第二个元素
1 | ['foo', 'bar', 'baz'] |
- list常用来实现一个迭代器或者生成表达式:
1 | gen = range(10) |
输出结果如下:
1 | range(0, 10) |
2.2 添加和删除元素
1 | b_list = ['foo', 'bar', 'baz'] |
可以看到,添加元素有append, insert方法,删除元素有pop, remove方法,其他有关list的方法,可以在ipython中使用TAB键进行查看;
如果不考虑性能,可以使用append和remove,不然可以使用Python的另外一个数据结构 ‘multiset’,以此来优化性能;
输出结果:
1 | ['foo', 'bar', 'baz', 'dwarf'] |
2.3 列表的拼接和组合
1 | print([4, None, 'foo'] + [7, 8, (2, 3)]) |
以上代码输出结果:
1 | [4, None, 'foo', 7, 8, (2, 3)] |
列表的拼接 “+” 会创建出一个新的对象并进行拷贝,如果构造了一个数据量大的列表,再对其进行copy操作,将会非常影响性能,此时建议使用extend进行扩展组合操作;
1 | everything = [] |
2.4 排序
- 排序
1 | a = [7, 2, 5, 1, 3] |
输出结果:
1 | [1, 2, 3, 5, 7] |
注意:列表排序并不需要重新创建对象,直接在原有对象上进行操作(in-place);
- 二分查找与有序列表维护
Python内置 bisect模块实现了有序列表的二分查找和插入,看下以下几个操作:
1 | import bisect |
注意:
- bisect 方法仅获取了index,并没有对元素进行插入操作;
- bisect模块并不会对list进行判断是否有序,所以,使用前需要进行排序,否则可能出现操作返回错误的结果;
以上代码执行结果:
1 | 4 # 优先靠右,所以获取到的index为4 |
2.5 切片
1 | seq = [7, 2, 3, 7, 5, 6, 0, 1] |
[start:stop:step],左闭右开,包含start开始的元素,不包含stop的元素
1 | [2, 3, 7, 5] |
内置序列函数(Built-in Sequence Functions)
Python包含三种主要的序列类型:list, tuple, range;还有其他的序列类型,包含二进制数据(binary data)和文本字符串(text strings);
3.1 enumerate
按照以往循环一个列表可能的操作是下面这样:
1 | i = 0 |
Python内置了枚举操作,并返回对应的index和value:
1 | some_list = ['foo', 'bar', 'baz'] |
3.2 sorted
1 | print(sorted([7, 1, 2, 6, 0, 3, 2])) |
数字默认从大到小排序,字符串默认字母顺序排序
1 | [0, 1, 2, 2, 3, 6, 7] |
3.3 zip
zip将两组或者多组可迭代的对象打包成一对对的元组
1 | seq1 = ['foo', 'bar', 'baz'] |
两种常用的zip方法:
1 | # 与enumerate结合 |
3.4 reversed
1 | list(reversed(range(10))) # 序列翻转 |
注意:reversed是个生成表达式(generator),需要搭配list或者for循环使用,reversed()本身返回的是一个迭代器对象。
下一篇文章会介绍一下其他的内置数据结构,包含字典(dict)、集合(set),以及他们和list的对比;才疏学浅,如有错误,还望联系并指出。