《Python数据科学指南》——1.4 使用元组

    xiaoxiao2024-05-30  97

    本节书摘来自异步社区《Python数据科学指南》一书中的第1章,第1.4节,作者[印度] Gopi Subramanian ,方延风 刘丹 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.4 使用元组

    在Python中,元组是一种顺序型的容器对象。元组是不可变的,元组中的元素由逗号分隔开,可以对不同类别构成的对象进行排序,不允许插入操作,支持以下操作。

    in和not in。

    比较、串联、切片和索引。

    min ()和max ()。

    1.4.1 准备工作

    我们讲解字典的时候,描述了完整的功能,对于元组,我们通过一些小段的代码来聚焦于元组的创建与维护操作。

    1.4.2 操作方法

    先让我们看看一些元组创建和维护的示例代码。

    # 1.创建一个元组 a_tuple = (1,2,'a') b_tuple =1,2,'c' # 2.利用索引访问元组的元素 print b_tuple[0] print b_tuple[-1] # 3.元组的元素值是无法修改的,如下的语句将返回一个错误 try: b_tuple[0] = 20 except: print "Cannot change value of tuple by index" # 4.虽然元组是不可变的,但是元素的元组可以是一个可变的对象 # 在如下的代码中,元组的元组是一个列表 c_tuple =(1,2,[10,20,30]) c_tuple[2][0] = 100 # 5.元组一旦被创建,无法像列表那样进行扩展 # 不过,两个元组可以串联在一起 print a_tuple + b_tuple # 6.对元组进行切片 a =(1,2,3,4,5,6,7,8,9,10) print a[1:] print a[1:3] print a[1:6:2] print a[:-1] # 7.对元组求min和max值 print min(a),max(a) # 8.包含于与非包含于 if 1 in a: print "Element 1 is available in tuple a" else: print "Element 1 is not available in tuple a"

    1.4.3 工作原理

    在第1步中,我们创建了一个元组,严格来说,括号并不是必需的,不过它提高了代码的可读性。我们创建的是一个多种对象组成的元组,有数值、字符串等类型。第2步演示了通过索引来访问元组的细节,索引下标是从零开始。如果下标是负数,则从相反的方向访问元组的元素,print语句的输出结果如下。

    >>> print b_tuple[0] 1 >>> print b_tuple[-1] c >>>

    Python的元组下标从零开始,元组是不可变的。在第3步中,我们能看到元组最重要的属性:不可变。我们无法改变一个元组的元素的值,示例代码的第3步会导致编译器抛出一个错误。

    Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment

    这显得有点过于严格,然而这种特性从数据科学的观点来说有着重要的意义。

    开发机器学习程序时,特别是从原始数据中生成特征值的时候,请创建特征值元组,这样数值就不会被下游的代码改变。

    这些特征值保存在元组里,下游的代码就无法意外地修改特征值。

    不过,我们需要指出,元组可以采用可变的对象作为它的成员,例如列表对象。像第4步中演示的元组,它的第3个元素就是一个列表对象,我们可以试试修改列表中的元素。

    c_tuple[2][0] = 100

    通过以下语句来打印输出元组。

    print c_tuple

    我们会得到如下的输出结果。

    (1, 2, [100, 20, 30])

    你能看到,列表的第1个元素的值已经被修改为100。

    在第5步中,我们将两个元组串联起来,在机器学习程序开发中,常常有不同模块生成不同的特征值,此时使用元组串联是一个很好的选择。

    例如:你有一个模块用于创建词袋模型的特征值,而另一个模块为了典型的文本分类而创建数值特征,这些模块都可以将输出结果保存到元组中,这样最终的模块可以连接所有的元组生成完整的特征值向量。

    由于不可变的特性,元组不像列表那样可以在创建之后进行扩展,它不支持append函数。元组的不可变特性的另一个好处是它可以作为字典的键。

    一般来说,当创建字典的键时,我们需要使用自定义的分隔符来连接不同的字符串,以此创建一个唯一的键。如果你使用元组,元组里的各个字符串可以对应作为字典的键。

    这样可以大大提高程序输出结果的可读性,另外还能避免键在手动组合的时候产生难以觉察的错误。

    在第6步中,我们讲述了元组的切片操作,一般地,切片参数需要3个冒号分隔的数字参数,第1个数是切片开始的位置,第2个是结束的位置,最后一个是步长。第6步的示例中也可以这样表示。

    print a[1:]

    打印输出的结果如下。

    (2, 3, 4, 5, 6, 7, 8, 9, 10)

    在这个示例中,我们只给出了开始位置(记住:索引起始于零),我们得到的是元组从索引值1开始的切片。再看另一个示例。

    print a[1:3]

    打印输出的结果如下。

    (2, 3)

    这样,我们指定了起始位置为1,结束位置为3。

    切片操作是右侧结束。

    虽然我们指定了结束位置为3,但输出的结果返回的值实际只到位置2,提前了一位。我们得到的是第2和第3位的部分。最后,我们来看看提供全部3个参数:起始位置、结束位置和步长。

    print a[1:6:2]

    打印输出的结果如下。

    (2, 4,6)

    除了起始和结束位置,我们设置了步长为2,上面的输出结果显示了每次输出都跳两个位置。

    我们再来看看位置索引值为负数的情形。

    print a[:-1]

    打印输出的结果如下。

    (1,2, 3, 4, 5, 6, 7, 8, 9)

    除了最后一个元素,全部的元素都被打印显示了。

    print a[::-1]

    更深入地思考一下,上面这个语句的输出结果如下所示——拥有好奇心的读者应该能探索出为何得到这样的结果。

    (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

    在第7步中,我们通过min ()和max ()函数来获取元组中的最小和最大值。

    >>> print min(a), max(a) 1 10 >>>

    在第8步中,我们展示了包含于、非包含于两种条件操作,这两种操作常常被用来检测某个元素是否存在于元组中。

    if 1 in a: print "Element 1 is available in tuple a" else: print "Element 1 is available in tuple a"

    1.4.4 更多内容

    前一小节中,我们通过索引访问元组的元素。为了提高程序的可读性,我们会给元组的每个元素取一个名字,并通过名字来访问这些元素,这就是命名元组的来由,下面的URL提供了很好的命名元组文档。

    https://docs.python.org/2/library/collections.html#collections.namedtuple。

    我们来看一个简单的命名元组应用示例。

    from collections import namedtuple vector = namedtuple("Dimension",'x y z') vec_1 = vector(1,1,1) vec_2 = vector(1,0,1) manhattan_distance = abs(vec_1.x - vec_2.x) + abs(vec_1.y - vec_2.y) \ + abs(vec_1.z - vec_2.z) print "Manhattan distance between vectors = %d"%(manhattan_distance)

    你可能已经注意到,我们采用了vec_1.x和vec_1.y等对象符号来访问vec_1和vec_2的元素。相较于使用元组的索引,这样的代码可读性更好。vec_1.x和vec_1[0]是等价的。

    1.4.5 参考资料

    第3章“数据分析——探索与争鸣”中3.16节“词袋模型表示文本”的相关内容。

    最新回复(0)