列表类型也是序列式的数据类型,可以通过下标或者切片操作来访问。能保留任意数目的Python 对象的灵活的容器。不仅可以包含Python 的标准类型,而且可以用用户定义的对象作为自己的元素.列表可以包含不同类型的对象,而且要比C 或者Python 自己的数组类型(包含在array 扩展包中)都要灵活.因为数组类型所有的元素只能是一种类型.
列表可以执行pop,empt,sort,reverse 等操作.列表也可以添加或者减少元素.还可以跟其他的列表结合或者把一个列表分成几个.可以对单独一个元素或者多个元素执行insert,update,或者remove 操作.
创建列表:
>>> alist=[None,'ddsds',4,56,['ds','erer']]
>>> alist
[None, 'ddsds', 4, 56, ['ds', 'erer']]
>>> alist[0]
>>> alist[1]
'ddsds'
>>> alist[2]
4
>>> alist[4]
['ds', 'erer']
>>> alist[4][1]
'erer'
更新列表:
列表是可以更新的,有两种方法:
1通过在等号的左边指定一个索引或者索引范围的方式来更新一个或几个元素,
2可以用append()方法来追加元素到列表中去.
更新和字符串的改变有区别,字符串的改变通常是将另一块内存指向原来的内存空间。
>>> id(alist)
12210008
>>>
>>>
>>> alist.append('b')
>>> id(alist)
12210008
>>>
>>>
>>> a="atr"
>>> id(a)
12227672
>>> a=a+'fg'
>>> a
'atrfg'
>>> id(a)
12212000
>>>
删除列表:
也有两种方法:
del 和remove,del适合在知道要删除的确切元素的位置的情况下,而remove则适合在仅仅知道删除元素的情况下。
或者使用pop也可以删除元素:
>>> alist
[None, 'ddsds', 4, 56, ['ds', 'erer'], 'gfgfg,[]', 'b']
>>> del alist[0]
>>> alist
['ddsds', 4, 56, ['ds', 'erer'], 'gfgfg,[]', 'b']
>>> alist.remove(4)
>>> alist
['ddsds', 56, ['ds', 'erer'], 'gfgfg,[]', 'b']
>>> alist.pop(1)
56
The pop() method is only supported by the list and array types. The optional argument i defaults to -1, so that by default the last item is removed and returned.
列表的成员关系操作符:
>>> alist
[['ds', 'erer'], 34, 'ffdfd']
>>>
>>>
>>>
>>> 34 in alist
True
>>> 'ds' in alist
False
>>>
>>>
>>> 'ds' not in alist
True
>>> 'ds' in alist[0]
True
连接操作符:
>>> alist
[['ds', 'erer'], 34, 'ffdfd']
>>>
>>>
>>>
>>> 34 in alist
True
>>> ds in alist
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ds' is not defined
>>> 'ds' in alist
False
>>>
>>>
>>> 'ds' not in alist
True
>>> 'ds' in alist[0]
True
>>> alist
[['ds', 'erer'], 34, 'ffdfd']
>>>
>>>
>>>
>>> 34 in alist
True
>>> ds in alist
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ds' is not defined
>>> 'ds' in alist
False
>>>
>>>
>>> 'ds' not in alist
True
>>> 'ds' in alist[0]
True
.使用extend()方法比连接操作的一个优点是它实际上
是把新列表添加到了原有的列表里面,而不是像连接操作那样新建一个列表
序列的cmp算法:
1. 对两个列表的元素进行比较.
2. 如果比较的元素是同类型的,则比较其值,返回结果.
3. 如果两个元素不是同一种类型,则检查它们是否是数字.
a. 如果是数字,执行必要的数字强制类型转换,然后比较.
b. 如果有一方的元素是数字,则另一方的元素"大"(数字是"最小的")
c. 否则,通过类型名字的字母顺序进行比较.
4. 如果有一个列表首先到达末尾,则另一个长一点的列表"大".
5. 如果我们用尽了两个列表的元素而且所有元素都是相等的,那么结果就是个平局,就
是说返回一个0.
>>> clist=['A']
>>> dlist=[132323]
>>> cmp(dlist,clist)
-1
sorted() and reversed()
>>> s = ['They', 'stamp', 'them', 'when', "they're", 'small']
>>> for t in reversed(s):
... print t,
...
small they're when them stamp They
>>> sorted(s)
['They', 'small', 'stamp', 'them', "they're", 'when']
初学者使用字符串,应该注意是如何把单引号和双引号的使用矛盾和谐掉.同时还要注意字
符串排序使用的是字典序,而不是字母序(字母'T'的ASCII 码值要比字母'a'的还要靠前)
The sort() and reverse() methods modify the list in place for economy of space when sorting or reversing a large list. To remind you that they operate by side effect, they don’t return the sorted or reversed list.
sort():
>>> music_media.sort()# 没有输出?
>>>
在使用可变对象的方法如sort(),extend()和reverse()的时候要注意,这些操作会在列表中原地执行操作,也就是说现有的列表内容会被改变,但是没有返回值!
Python中的拷贝:深拷贝和浅拷贝
copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作
摘抄:
对象赋值实际上是简单的对象引用。也就是说当你创建一个对象,然后把它赋给另一个变量的时候,Python 并没有拷贝这个对象,而是拷贝了这个对象的引用。
比如,假设你想创建一对小夫妻的通用档案,名为person.然后你分别为他俩拷贝一份。在下面的例子中,我们展示了两种拷贝对象的方式,一种使用了切片操作,另一种用了工厂方法,为了区分出三个不同的对象,我们使用id()内建函数来显示每个对象的标识符。(我们还可以用is 操作符来做相同的事情)
>>> person = ['name', ['savings', 100.00]]
>>> hubby = person[:] # slice copy
>>> wifey = list(person) # fac func copy
>>> [id(x) for x in person, hubby, wifey]
[11826320, 12223552, 11850936]
为他们创建了初始有$100 的个人存款帐户。用户名改为定制的名字。但是,当丈夫取走$50后,他的行为影响到了他妻子的账户,虽然我们进行了分开的拷贝作(当然,前提是我们希望他们每个人都拥有自己单独的帐号,而不是一个单一的联合帐号。)为什么会这样呢?
>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> hubby, wifey
(['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 50.0]])
原因是我们仅仅做了一个浅拷贝。对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是.序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:],(2)利用工厂函数,比如list(),dict()等,(3)使用copy 模块的copy 函数.你的下一个问题可能是:当妻子的名字被赋值,为什么丈夫的名字没有受到影响?难道它们
的名字现在不应该都是'jane'了吗?为什么名字没有变成一样的呢?怎么会是这样呢?这是因为在这两个列表的两个对象中,第一个对象是不可变的(是个字符串类型),而第二个是可变的(一个列表).正因为如此,当进行浅拷贝时,字符串被显式的拷贝,并新创建了一个字符串对象,而列表元素只是把它的引用复制了一下,并不是它的成员.所以改变名字没有任何问题,但是更改他们银行账号的任何信息都会引发问题.现在,让我们分别看一下每个列表的元素的对象ID 值,注意,银行账号对象是同一个对象,这也是为什么对一个对象进行修改会影响到另一个的原因.注意在我们改变他们的名字后,新的名字字符串是如何替换原有'名字'字符串的.
BEFORE:
>>> [id(x) for x in hubby]
[9919616, 11826320]
>>> [id(x) for x in wifey]
[9919616, 11826320]
AFTER:
>>> [id(x) for x in hubby]
[12092832, 11826320]
>>> [id(x) for x in wifey]
[12191712, 11826320]
假设我们要给这对夫妻创建一个联合账户,那这是一个非常棒的方案,但是,如果需要的是两个分离账户,就需要作些改动了.要得到一个完全拷贝或者说深拷贝--创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用--需要copy.deepcopy()函数.我们使用深拷贝来重写整个例子.
>>> person = ['name', ['savings', 100.00]]
>>> hubby = person
>>> import copy
>>> wifey = copy.deepcopy(person)
>>> [id(x) for x in person, hubby, wifey]
[12242056, 12242056, 12224232]
>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> hubby, wifey
(['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 100.0]])
这就是我们想要的方式,作为验证,让我们确认一下所有四个对象都是不同的.
>>> [id(x) for x in hubby]
[12191712, 11826280]
>>> [id(x) for x in wifey]
[12114080, 12224792]
以下有几点关于拷贝操作的警告。第一,非容器类型(比如数字,字符串和其他"原子"类型的对象,像代码,类型和xrange 对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成的.第二,如果元组变量只包含原子类型对象,对它的深拷贝将不会进行.如果我们把账户信息改成元组类型,那么即便按我们的要求使用深拷贝操作也只能得到一个浅拷贝:
>>> person = ['name', ('savings', 100.00)]
>>> newPerson = copy.deepcopy(person)
>>> [id(x) for x in person, newPerson]
[12225352, 12226112]
>>> [id(x) for x in person]
[9919616, 11800088]
>>> [id(x) for x in newPerson]
[9919616, 11800088]