牛骨文教育服务平台(让学习变的简单)
博文笔记

如何分辨python语言中列表、元组的区别

创建时间:2017-07-07 投稿人: 浏览次数:502

Python中大部分对象从逻辑上来说都是不可变的,因为默认使用id作为hash值,这表明在对象整个生命周期中hash保持不变,==操作也返回相同的结果,因此哪怕属性改变了,从Python的角度来看这个对象也是不变的。

1. 列表以及元组的详细简介

  跟字符串一样,列表和元组也是序列型的数据类型,可以通过下标或者切片来访问某一个或者某一连续的元素,列表更灵活的是列表和元组可以包含不同类型的对象。列表和元组在很多操作上是一样的,最大的不同是:元组跟字符串一样,是不可变的。这两种数据类型如此相似,那为何有了列表还需要元组呢?因为在某些情况下,使用其中的一种类型要优于另一种。如:(1)你需要把一些敏感数据传递给一个并不了解的函数,你希望你的数据不被这个函数修改,此时当然选元组了。(2)你在处理动态数据时,需要经常更新这个数据结合,此时就应该选列表了。因此,这两种数据类型各有各的用处,它们之间的转换也十分的方便,通过内建函数list()把一个序列类型转换成列表,通过tuple()把一个序列类型转换成元组。

python语言中列表、元组的区别_python编程_python入门_字符串_课课家教育

  >>> 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"]

  2. 列表常用操作

  2.1 列表解析

  >>> [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()函数返回一个列表

  2.2 常用内建函数

  (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

  (2)max()和min()

  >>> s = ["alex","3","zhou"]

  >>> max(s)

  "zhou"

  >>> min(s)

  "3"

  (3)sorted()和reverse()

  排序和逆序

  >>> s = ["alex","3","zhou"]

  >>> s.reverse()

  >>> s

  ["zhou", "3", "alex"]

  >>> sorted(s)

  ["3", "alex", "zhou"]

  (4)enumerate()和zip()

  enumerate函数可以同时打印index和value,zip函数接受任意多个序列作为参数,将所有序列按相同的索引组合成一个元素是各个序列合并成的元组的新序列,新的序列的长度以参数中最短的序列为准。

  Python中,有3种内建的数据结构:列表、元组和字典。

  list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目。列表中的项目。列表中的项目应该包括在方括号中,这样python就知道你是在指明一个列表。一旦你创建了一个列表,你就可以添加,删除,或者是搜索列表中的项目。由于你可以增加或删除项目,我们说列表是可变的数据类型,即这种类型是可以被改变的,并且列表是可以嵌套的。

list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目

  实例:

  #coding=utf-8

  animalslist=["fox","tiger","rabbit","snake"]

  print "I don"t like these",len(animalslist),"animals..."

  for items in animalslist:

  print items,

  print "\n操作后"

  #对列表的操作,添加,删除,排序

  animalslist.append("pig")

  del animalslist[0]

  animalslist.sort()

  for i in range(0,len(animalslist)):

  print animalslist[i],

  结果:

  I don"t like these 4 animals...

  fox tiger rabbit snake

  操作后

  pig rabbit snake tiger

  >>> 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)

  reduce函数把列表的前两个元素作为参数传给function,返回计算的结果和列表的下一个元素重新作为function的参数,直到列表的最后一个元素。

  sum函数计算列表所有元素的总和,元素必须为数字。

  >>> s = ["a","b"]

  >>> sum(s)

  Traceback (most recent call last):

  File "", line 1, in

  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

  (6)list()和tuple()

  list函数和tuple函数把序列通过浅拷贝的方式创建一个列表或元组,常用于列表和元组间的相互转换。

  >>> l = [1,2,3]

  >>> tuple(l)

  (1, 2, 3)

  >>> t = (1,2,3)

  >>> list(t)

  [1, 2, 3]

  (7)列表内建函数

  list.append(obj)

  向列表中添加一个对象

  >>> l = [1,2,3]

  >>> l.append(4)

  >>> l

  [1, 2, 3, 4]

  list.count(obj)

  计算obj在列表中出现的次数

  >>> l = [1,1,1,2,2]

  >>> l.count(1)

  3

  list.extend(sequence)

  把序列sequence的内容添加到列表

  >>> l1 = [1,2]

  >>> l2 = [3,4]

  >>> l1.extend(l2)

  >>> l1

  [1, 2, 3, 4]

  list.index(obj,i=0,j=len(list))

  返回obj在列表中的索引值,如果不存在则抛出ValueError异常

  >>> l = [1,2,3,4]

  >>> l.index(1)

  0

  >>> l.index(5)

  Traceback (most recent call last):

  File "", line 1, in

  ValueError: list.index(x): x not in list

  list.insert(index,obj)

  在列表的指定索引处插入对象obj,如果index大于列表的长度,则插入到列表最后

  >>> 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"]

  list.pop(index=-1)

  删除并返回列表中指定位置的对象,默认是最后一个元素,若index超出列表长度,则抛出IndexError异常

  >>> 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

  list.remove(obj)

  从列表中删除对象,若对象不存在则抛出ValueError异常

  >>> l = [1,2,3]

  >>> l.remove(1)

  >>> l

  [2, 3]

  >>> l.remove("a")

  Traceback (most recent call last):

  File "", line 1, in

  ValueError: list.remove(x): x not in list

  3. 元组常用操作

  3.1 元组元素的可变性

  元组跟列表的操作很相近,具体操作可以参考以上列表操作,不过由于元组的不可变特效,可以将元组作为字典的key。要注意的是:元组的不可变特效只是对于元组本身而言,如果元组内的元素是可变的对象,是可以改变其值的。

  >>> t = ([1,2],3,4)

  >>> t[0][0] = 3

  >>> t

  ([3, 2], 3, 4)

  >>> t[1] = 5

  Traceback (most recent call last):

  File "", line 1, in

  TypeError: "tuple" object does not support item assignment

  3.2 单元素元组

  由于圆括号被重载,单元素元组需要在后面添加一个逗号。

  >>> t = (1)

  >>> type(t)

  >>> t = (1,)

  >>> type(t)

  4. python对象浅拷贝和深拷贝

  浅拷贝是新建一个跟原来类型一样的对象(身份是新的: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]

  从上面可以看出,各个对象的id是不一样的

  4.2 尝试改变各列表的值,看看会发生什么事

  >>> 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的值是一样的,表明各对象中列表的内容都是指向同一对象的,所以发生了浅拷贝操作。

从测试结果可以看出,非容器类型(数字、字符串等)没有发生拷贝操作,各列表中的user_id互不影响,id也不一样;改变了alex中列表的值,其它对象中列表的值也受到了影响,并且id的值是一样的,表明各对象中列表的内容都是指向同一对象的,所以发生了浅拷贝操作。

  4.3 进行深拷贝操作

  >>> 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"]])

  可以看到对象jiang的id跟其它浅拷贝对象是不一样的,改变对象alex列表中元素的值对jiang对象没有任何影响。注意:如果对象是不可变类型,如元组或者数字、字符串等,那么对它进行深拷贝也只能得到浅拷贝对象。

  >>> 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]

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。