跟字符串一样,列表和元组也是序列型的数据类型,可以通过下标或者切片来访问某一个或者某一连续的元素,列表更灵活的是列表和元组可以包含不同类型的对象。列表和元组在很多操作上是一样的,最大的不同是:元组跟字符串一样,是不可变的。这两种数据类型如此相似,那为何有了列表还需要元组呢?因为在某些情况下,使用其中的一种类型要优于另一种。如:(1)你需要把一些敏感数据传递给一个并不了解的函数,你希望你的数据不被这个函数修改,此时当然选元组了。(2)你在处理动态数据时,需要经常更新这个数据结合,此时就应该选列表了。因此,这两种数据类型各有各的用处,它们之间的转换也十分的方便,通过内建函数list()把一个序列类型转换成列表,通过tuple()把一个序列类型转换成元组。
>>> s = u'alexzhou' >>> list(s) [u'a', u'l', u'e', u'x', u'z', u'h', u'o', u'u'] >>> tuple(s) (u'a', u'l', u'e', u'x', u'z', u'h', u'o', u'u') >>> s = ['alex','zhou'] >>> tuple(s) ('alex', 'zhou') >>> s = ('alex','zhou') >>> list(s) ['alex', 'zhou']
>>> [i for i in range(8)] [0, 1, 2, 3, 4, 5, 6, 7] >>> [i+2 for i in range(8)] [2, 3, 4, 5, 6, 7, 8, 9]
ps:range()函数返回一个列表
(1)cmp()
列表之间的比较就是比较列表中的元素,遵循以下规则。
1.如果比较的元素是同类型的,则比较其值,返回结果.
2.如果两个元素不是同一种类型,则检查它们是否是数字.
a. 如果是数字,执行必要的数字强制类型转换,然后比较.
b. 如果有一方的元素是数字,则另一方的元素”大”(数字是”最小的”)
c. 否则,通过类型名字的字母顺序进行比较.
3.如果有一个列表首先到达末尾,则另一个长一点的列表”大”.
4.如果两个列表的所有元素都是相等的,那么返回0,表示两列表大小相等.
>>> l1 = ['a','b'] >>> l2 = ['x','a'] >>> l3 = ['a','b'] >>> l4 = ['x','a','b'] >>> l5 = ['2','x'] >>> cmp(l1,l2) -1 >>> cmp(l1,l3) 0 >>> cmp(l2,l4) -1 >>> cmp(l1,l5) 1
>>> s = ['alex','3','zhou'] >>> max(s) 'zhou' >>> min(s) '3'
>>> s = ['alex','3','zhou'] >>> s.reverse() >>> s ['zhou', '3', 'alex'] >>> sorted(s) ['3', 'alex', 'zhou']
>>> sorted(s) ['3', 'alex', 'zhou'] >>> for i,obj in enumerate(s): ... print i,obj ... 0 alex 1 3 2 zhou >>> s = ['alex','3','zhou'] >>> z = ['zhou','4','alex'] >>> zip(s,z) [('alex', 'zhou'), ('3', '4'), ('zhou', 'alex')] >>> for i,j in zip(s,z): ... print i,j ... alex zhou 3 4 zhou alex(5)reduce(function,sequence)和sum(sequence)
>>> s = ['a','b'] >>> sum(s) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'str' >>> s = [1,2] >>> sum(s) 3 >>> s = [1.5,2] >>> sum(s) 3.5 >>>def add(x,y): ... return x+y >>>reduce(add,range(10)) 45 >>>sum(range(5),5) 15
>>> l = [1,2,3] >>> tuple(l) (1, 2, 3) >>> t = (1,2,3) >>> list(t) [1, 2, 3]
>>> l = [1,2,3] >>> l.append(4) >>> l [1, 2, 3, 4]
>>> l = [1,1,1,2,2] >>> l.count(1) 3
>>> l1 = [1,2] >>> l2 = [3,4] >>> l1.extend(l2) >>> l1 [1, 2, 3, 4]
>>> l = [1,2,3,4] >>> l.index(1) 0 >>> l.index(5) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.index(x): x not in list
>>> l = [1,2,3,4] >>> l.insert(1,'a') >>> l [1, 'a', 2, 3, 4] >>> l.insert(9,'a') >>> l [1, 'a', 2, 3, 4, 'a', 'a']
>>> l = [1,2,3,4] >>> l.pop() 4 >>> l [1, 2, 3] >>> l.pop(0) 1 >>> l [2, 3] >>>l.pop(9) Traceback (most recent call last): File "", line 1, in IndexError: pop index out of range
>>> l = [1,2,3] >>> l.remove(1) >>> l [2, 3] >>> l.remove('a') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
元组跟列表的操作很相近,具体操作可以参考以上列表操作,不过由于元组的不可变特效,可以将元组作为字典的key。要注意的是:元组的不可变特效只是对于元组本身而言,如果元组内的元素是可变的对象,是可以改变其值的。
>>> t = ([1,2],3,4) >>> t[0][0] = 3 >>> t ([3, 2], 3, 4) >>> t[1] = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
由于圆括号被重载,单元素元组需要在后面添加一个逗号。
>>> t = (1) >>> type(t) <type 'int'> >>> t = (1,) >>> type(t) <type 'tuple'>
浅拷贝是新建一个跟原来类型一样的对象(身份是新的:id(obj)),不过其内容是原来对象元素的引用(内容是旧的),是序列类型对象默认的拷贝方式,
深拷贝则包括对象及其内容都是新的,下面的这些操作是浅拷贝。
(1)完全切片操作[:]
(2)利用工厂函数,比如 list(),dict()等
(3)使用 copy 模块的 copy 函数
下面通过一个例子来说明浅拷贝和深拷贝
4.1 创建一个列表,并采用上面三种方式进行浅拷贝
>>> user = ['user_id',['username','alexzhou']] >>> alex = user[:] >>> zhou = list(user) >>> import copy >>> hai = copy.copy(user) >>> [id(x) for x in user,alex,zhou,hai] [140325195435976, 140325195478368, 140325195480528, 140325195480600]
>>> alex[0] = '1' >>> zhou[0] = '2' >>> hai[0] = '3' >>> user,alex,zhou,hai (['user_id', ['username', 'alexzhou']], ['1', ['username', 'alexzhou']], ['2', ['username', 'alexzhou']], ['3', ['username', 'alexzhou']]) >>> alex[1][1] = 'test' >>> user,alex,zhou,hai (['user_id', ['username', 'test']], ['1', ['username', 'test']], ['2', ['username', 'test']], ['3', ['username', 'test']]) >>> [id(x) for x in alex] [140325295415488, 140325195435400] >>> [id(x) for x in zhou] [140325295406992, 140325195435400] >>> [id(x) for x in hai] [140325195481664, 140325195435400]从测试结果可以看出,非容器类型(数字、字符串等)没有发生拷贝操作,各列表中的user_id互不影响,id也不一样;改变了alex中列表的值,其它对象中列表的值也受到了影响,并且id的值是一样的,表明各对象中列表的内容都是指向同一对象的,所以发生了浅拷贝操作。
>>> jiang = copy.deepcopy(user) >>> jiang ['user_id', ['username', 'test']] >>> [id(x) for x in jiang] [140325195467488, 140325195480456] >>> alex[1][1] = 'alex' >>> alex,zhou,hai,jiang (['1', ['username', 'alex']], ['2', ['username', 'alex']], ['3', ['username', 'alex']], ['user_id', ['username', 'test']])
>>> user1 = ['user_id',('username','alex')] >>> user2 = copy.deepcopy(user1) >>> [id(x) for x in user1,user2] [140325195477936, 140325195480168] >>> [id(x) for x in user1] [140325195467488, 140325195435112] >>> [id(x) for x in user2] [140325195467488, 140325195435112]
由于元组本身是不可变的,可以看到进行深拷贝后user1对象和user2对象中的元组
id
是一样的,
本质上只进行了浅拷贝。
转载请注明来自:Alex Zhou,本文链接:http://codingnow.cn/python/325.html