美文网首页
6. 数据类型 —— 元组

6. 数据类型 —— 元组

作者: 梦回吹角连营 | 来源:发表于2014-12-17 20:48 被阅读0次

    元组属于容器存储、不可变、顺序访问的数据类型。元组可以看作是不可变的列表,除了这一点外元组和列表的特征十分相似。

    1. 创建元组

    元组使用 ( ) 来定义,直接把一个被 ( ) 包含,由 , 分隔的数据赋值给一个变量即可创建元组对象。

    >>> tup = (1, 2, 3)                                 # 通过直接将由圆括号 () 括起来的对象赋值给变量创建元组
    >>> tup
    (1, 2, 3)
    >>> tup = (1, )                                     # 如果元组对象中只有一个元素时,必须在元素后添加一个 ',' 否则不会创建元组
    >>> tup
    (1, )
    >>> tup = (1, 'a', [1])                             # 和列表一样,元组的元素可以是任何数据类型
    >>> tup
    (1, 'a', [1])
    

    元组同样可以使用 tuple() 函数来创建元组对象

    >>> tup = tuple([1, 2, 3])
    >>> tup
    (1, 2, 3)
    

    2. 元组的基本操作

    • 访问元组中的元素

      元素属于顺序访问的序列类型,因此可以通过索引和切片操作对元组中的元素进行访问

    tup = (1, 2, 3, 4, 5, 6, 7)
    tup[0] # 元组索引和字符串一样,从 0 开始,最大为列表的长度 - 1
    1
    tup[-1] # 使用负索引访问元组元素
    7
    tup[1:3] # 元组的切片操作返回一个包含元组部分元素的新的元组
    (2, 3)
    tup[::-1] # 反序访问元组
    (7, 6, 5, 4, 3, 2, 1)
    tup = ([1, 2, 3],)
    tup[0][1] # 元组中嵌套的任意序列数据类型的访问,注意元组中只有一个元素时,元素后边要加 ','
    2
    ```

    • 元组不可变性

      元组中的元素一般来说是不可以改变的,但由于元组中可以包含列表、字典等其他数据类型,而这些数据类型中的元素是可以改变的,因此在这种情况下元组发生了 "改变"。元组的不可变性仅适用于元组本身元素顶层,而非其元素的内容

    >>> tup = ([1, 2, 3], )
    >>> tup[0][1] = 7                                    # 改变元组中列表元素的值,可以在 "改变" 元组
    >>> tup
    ([1, 7, 3])
    >>> tup[0] = 1                                       # 如果直接更改元组的元素会引发一个 TypeError 异常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    

    3. 元组的一些操作符和函数

    元组属于序列数据类型,因此大部分序列操作和函数适用于元组,但由于元组的不可变性,一些需要对序列对中元素进行修改的函数并未对元组进行实现。

    操作符
    • + 操作符:对元组使用 + 操作符可以将两个元组连接在一起创建一个新的元组

    (1, 2) + (3, 4)
    (1, 2, 3, 4) # 直接生成一个新的元组而并非对原元组进行修改
    ```

    • * 操作符:使用 * 操作符可以将元组重复 N 次

    (1, ) * 7
    (1, 1, 1, 1, 1, 1, 1)
    ```

    • innot in:成员关系操作,测试对象是否是元组的元素

    tup = (1, 2, 3)
    1 not in tup
    False
    1 in tup
    True
    ```

    函数

    元组很像列表,但由于元组的不可变性,因此在进行绝大多数函数操作时,首先将元组转换为列表,然后继续后边的操作。

    >>> tup = (3, 1, 2)
    >>> li = list(tup)                                    # 首先将元组转换为列表
    >>> li.sort()                                         # 对列表进行排序
    >>> tup = tuple(li)                                   # 将排好序的列表转化为元组
    >>> tup
    (1, 2, 3) 
    

    元组仅有的两个方法 indexcount,这两个方法对元组跟对列表一样

    >>> tup = (1, 2, 3, 1)
    >>> tup.index(1)
    0
    >>> tup.count(1)
    2
    

    4. 元组的意义

    元组的意义在于它的不可变性。一个元组对象的值不会发生改变,也就意味着它们可以通过 hash 算法得到的值时固定的。因此元组可以作为字典的键。这是元组的一个典型应用场景,通常来说,元组用在需要确保数据不会被修改的时候。

    参考:
    Tuple

    复制对象 —— 浅复制和深复制

    当我们为变量进行赋值时,只是创建了对对象的引用,而不是将对象进行复制。当将其赋值给另外一个变量时,也并没有复制这个对象,而是复制了引用。

    >>> a = 1
    >>> id(a)
    8109160
    >>> b = a
    >>> id(b)
    8109160                             # 变量 a 和变量 b 指向同一个对象 
    

    使用切片操作和函数进行对象的复制

    >>> li = [1, [2, 3]]
    >>> a = li[:]                      # 使用切片操作对 li 进行复制
    >>> b = list(li)                   # 使用 list() 函数对 li 进行复制
    >>> a[0] = 7                    
    >>> a
    [7, [2, 3]]                        # 修改了 a 的第一个元素
    >>> b 
    [1, [2, 3]]                        # 并没有对 b 造成改变
    >>> a[1][0] = 8
    >>> a
    [7, [8, 3]]                        # 将 a 中的列表元素中的元素值进行修改
    >>> b
    [1, [8, 3]]                        # b 中列表元素同样发生了改变
    

    发生上述情况的原因在于浅复制。对一个对象进行浅复制创建了一个新的对象,但对象的内容是对原来对象内容的引用。

    >>> id(a[1])
    139969576313056
    >>> id(b[1])
    139969576313056                    # 变量 a 和 b 对应的列表元素指向同一个对象,因此同时发生了改变
    >>> id(a[0])
    8109016
    >>> id(b[0])
    8109160                           # 由于数字、字符串等是不可变类型,因此改变该元素即赋值了一个新的对象 
    

    使用浅复制的方法:1)切片操作 [:];2)list()、dict() 等函数;3)使用 copy 模块中的 copy 函数

    如果需要得到一个完全不同的复制,需要使用 copy 的 copy.deepcopy() 函数,即深复制

    >>> import copy
    >>> a = li
    >>> b = copy.deepcopy(li)
    >>> id(a[1])
    139969576313056
    >>> id(b[1])
    139969576369112                    # a、b 中的列表元素为不同的引用
    
    • 浅复制和深复制只是针对除元组以外的容器数据类型。

    相关文章

      网友评论

          本文标题:6. 数据类型 —— 元组

          本文链接:https://www.haomeiwen.com/subject/kipotttx.html