1.2.2.2 容器
Python提供了许多有效的容器类型,其中存储了对象集合。
1.2.2.2.1 列表
列表是一个有序的对象集合,对象可以有多种类型。例如:
In [28]:
L = ['red', 'blue', 'green', 'black', 'white']
type(L)
Out[28]:
list
索引:访问包含在列表中的单个对象:
In [29]:
L[2]
Out[29]:
'green'
使用负索引,从结尾开始计数:
In [30]:
L[-1]
Out[30]:
'white'
In [31]:
L[-2]
Out[31]:
'black'
注意:索引从0开始(和C中一样),而不是1(像在Fortran或Matlab)!
切片:获得规律分布元素的子列表:
In [32]:
L
Out[32]:
['red', 'blue', 'green', 'black', 'white']
In [33]:
L[2:4]
Out[33]:
['green', 'black']
注意:L[start:stop]包含索引start<= i < stop的元素(i的范围从start到stop-1)。因此,L[start:stop]包含(stop-start)个元素。
切片语法:L[start:stop:stride]
所有切片参数都是可选的:
In [34]:
L
Out[34]:
['red', 'blue', 'green', 'black', 'white']
In [35]:
L[3:]
Out[35]:
['black', 'white']
In [36]:
L[:3]
Out[36]:
['red', 'blue', 'green']
列表是可变对象,可以被改变:
In [38]:
L[0] = 'yellow'
L
Out[38]:
['yellow', 'blue', 'green', 'black', 'white']
In [39]:
L[2:4] = ['gray', 'purple']
L
Out[39]:
['yellow', 'blue', 'gray', 'purple', 'white']
注:一个列表的元素可以有不同的类型:
In [40]:
L = [3, -200, 'hello']
L
Out[40]:
[3, -200, 'hello']
In [41]:
L[1], L[2]
Out[41]:
(-200, 'hello')
对于一个所有类型都相同的数值数据集合,使用Numpy模块提供的数组类型通常更有效。Numpy数组是包含固定大小项目的内存组块。使用Numpy数组,元素上的操作可以非常快速,因为元素均匀分布在内存上并且更多的操作是通过特殊的C函数而不是Python循环。
Python提供了一大组函数来修改或查询列表。这里是一些例子,更多内容,请见:http://docs.python.org/tutorial/datastructures.html#more-on-lists
添加和删除元素:
In [42]:
L = ['red', 'blue', 'green', 'black', 'white']
L.append('pink')
L
Out[42]:
['red', 'blue', 'green', 'black', 'white', 'pink']
In [43]:
L.pop() # 删除并返回最后一个项目
Out[43]:
'pink'
In [44]:
L
Out[44]:
['red', 'blue', 'green', 'black', 'white']
In [45]:
L.extend(['pink', 'purple']) # 扩展列表L,原地
L
In [46]:
L = L[:-2]
L
Out[46]:
['red', 'blue', 'green', 'black', 'white']
反转:
In [47]:
r = L[::-1]
r
Out[47]:
['white', 'black', 'green', 'blue', 'red']
In [48]:
r2 = list(L)
r2
Out[48]:
['red', 'blue', 'green', 'black', 'white']
In [49]:
r2.reverse() # 原对象
r2
Out[49]:
['white', 'black', 'green', 'blue', 'red']
串联和重复列表:
In [50]:
r + L
Out[50]:
['white',
'black',
'green',
'blue',
'red',
'red',
'blue',
'green',
'black',
'white']
In [51]:
r * 2
Out[51]:
['white',
'black',
'green',
'blue',
'red',
'white',
'black',
'green',
'blue',
'red']
排序:
In [52]:
sorted(r) # 新对象
Out[52]:
['black', 'blue', 'green', 'red', 'white']
In [53]:
r
Out[53]:
['white', 'black', 'green', 'blue', 'red']
In [55]:
r.sort() # 原对象
r
Out[55]:
['black', 'blue', 'green', 'red', 'white']
方法和面向对象编程
符号r.method() (即 r.append(3) and L.pop()) 是我们第一个关于面向对象编程的例子(OOP)。作为列表,对象r有可以以这种方式调用的方法函数。对于这篇教程不需要关于面向对象编程的更多知识,只需要理解这种符号。
发现方法:
提醒:在IPython中:tab完成 (按tab)
In [28]: r.<TAB>
r.__add__ r.__iadd__ r.__setattr__
r.__class__ r.__imul__ r.__setitem__
r.__contains__ r.__init__ r.__setslice__
r.__delattr__ r.__iter__ r.__sizeof__
r.__delitem__ r.__le__ r.__str__
r.__delslice__ r.__len__ r.__subclasshook__
r.__doc__ r.__lt__ r.append
r.__eq__ r.__mul__ r.count
r.__format__ r.__ne__ r.extend
r.__ge__ r.__new__ r.index
r.__getattribute__ r.__reduce__ r.insert
r.__getitem__ r.__reduce_ex__ r.pop
r.__getslice__ r.__repr__ r.remove
r.__gt__ r.__reversed__ r.reverse
r.__hash__ r.__rmul__ r.sort
1.2.2.2.2 字符
不同的字符语法(单引号、双引号或三个引号):
In [58]:
s = 'Hello, how are you?'
s = "Hi, what's up"
s = '''Hello,
how are you''' # 三个引号可以允许字符跨行
s = """Hi,
what's up?"""
'Hi, what's up?'
File "<ipython-input-58-dfe00f996c26>", line 7
'Hi, what's up?'
^
SyntaxError: invalid syntax
如果在字符中要是使用引号,那么应该嵌套使用,或者使用"\"进行转义,否则会报错。
换行的符号为 \n,tab符号是\t。
字符也是类似与列表的结合。因此,也可以使用相同的语法和规则索引和切片。
索引:
In [59]:
a = "hello"
a[0]
Out[59]:
'h'
In [60]:
a[1]
Out[60]:
'e'
In [61]:
a[-1]
Out[61]:
'o'
(记住负索引从右侧开始计数。)
切片:
In [64]:
a = "hello, world!"
a[3:6] # 第三到第六个(不包含)元素:元素3、4、5
Out[64]:
'lo,'
In [65]:
a[2:10:2] # 语法:a[开始:结束:步幅]
Out[65]:
'lo o'
In [66]:
a[::3] # 从开始到结尾,每隔3个字母
Out[66]:
'hl r!'
重音符号和特殊字符也可以被处理为Unicode字符(请见 http://docs.python.org/tutorial/introduction.html#unicode-strings)。
字符是不可变对象,不可能修改内容。不过可以从原始的字符中创建一个新的字符。
In [68]:
a = "hello, world!"
a[2] = 'z'
------------- ------------- ------------- ------------- -----------------------
TypeError Traceback (most recent call last)
<ipython-input-68-8f124c87c8cf> in <module>()
1 a = "hello, world!"
----> 2 a[2] = 'z'
TypeError: 'str' object does not support item assignment
In [69]:
a.replace('l', 'z', 1)
Out[69]:
'hezlo, world!'
In [70]:
a.replace('l', 'z')
Out[70]:
'hezzo, worzd!'
字符有许多有用的方法,比如上面的a.replace。回忆一下a.面向对象的符号,并且使用tab完成或者help(str)来搜索新的方法。and use tab completion or
更多内容 Python提供了操作的字符的高级可能性,看一下模式或格式。感兴趣的读者请参考:http://docs.python.org/library/stdtypes.html#string-methods 和 http://docs.python.org/library/string.html#new-string-formatting。
字符格式:
In [71]:
'An integer: %i; a float: %f; another string: %s' % (1, 0.1, 'string')
Out[71]:
'An integer: 1; a float: 0.100000; another string: string'
In [72]:
i = 102
filename = 'processing_of_dataset_%d.txt' % i
filename
Out[72]:
'processing_of_dataset_102.txt'
1.2.2.2.3. Dictionaries
字典本质上是一个映射键值的高效表格。它是一个无序的容器
In [74]:
tel = {'emmanuelle': 5752, 'sebastian': 5578}
tel['francis'] = 5915
tel
Out[74]:
{'emmanuelle': 5752, 'francis': 5915, 'sebastian': 5578}
In [75]:
tel['sebastian']
Out[75]:
5578
In [76]:
tel.keys()
Out[76]:
['sebastian', 'francis', 'emmanuelle']
In [77]:
tel.values()
Out[77]:
[5578, 5915, 5752]
它可以方便的以名字(日期的字符和名称等)存储和获取值。更多信息见 http://docs.python.org/tutorial/datastructures.html#dictionaries。
一个字典的键(代表值)可以有不同的类型:
In [78]:
d = {'a':1, 'b':2, 3:'hello'}
d
Out[78]:
{3: 'hello', 'a': 1, 'b': 2}
1.2.2.2.4. More container types
元组
元组本质上是不可变列表。元组的元素用括号包起来,或者只是用逗号分割:
In [79]:
t = 12345, 54321, 'hello!'
t[0]
Out[79]:
12345
In [80]:
t
Out[80]:
(12345, 54321, 'hello!')
In [81]:
u = (0, 2)
集合:无序,惟一项目:
In [82]:
s = set(('a', 'b', 'c', 'a'))
s
Out[82]:
{'a', 'b', 'c'}
In [83]:
s.difference(('a', 'b'))
Out[83]:
{'c'}
1.2.2.3. 赋值运算
赋值语句被用于(重)绑定名称与值,以及修改可变对象的项目或属性。
简单来说,它这样工作(简单赋值):
右侧表达式被评估,创建或获得产生的对象
左侧的名字被赋值或绑定到右侧的对象
需要注意的事情:
- 单个对象可以有多个绑定的名称:
In [84]:
a = [1, 2, 3]
b = a
a
Out[84]:
[1, 2, 3]
In [85]:
b
Out[85]:
[1, 2, 3]
In [86]:
a is b
Out[86]:
True
In [87]:
b[1] = 'hi!'
a
Out[87]:
[1, 'hi!', 3]
- 要在原地改变列表,请使用索引或切片:
In [88]:
a = [1, 2, 3]
a
Out[88]:
[1, 2, 3]
In [89]:
a = ['a', 'b', 'c'] # 创建另一个对象
a
Out[89]:
['a', 'b', 'c']
In [90]:
id(a)
Out[90]:
4394695640
In [91]:
a[:] = [1, 2, 3] # 在原地修改对象
a
Out[91]:
[1, 2, 3]
In [92]:
id(a)
Out[92]:
4394695640
与上一个id相同,你的可能有所不同…
这里的关键观点是可变 vs. 不可变
- 可变对象可以在原地修改
- 不可变对象一旦被创建就不可修改
更多内容在David M. Beazley的文章Python中的类型和对象中也可以找到关于以上问题非常不错的详尽解释。