Python笔记004-元组的拆包和命名元组

系统 1406 0

Python笔记004-元组的拆包和命名元组

以下是我学习《流畅的Python》后的个人笔记,现在拿出来和大家共享,希望能帮到各位Python学习者。

首次发表于: 微信公众号:科技老丁哥,ID: TechDing,敬请关注。

本篇主要知识点:

  1. 元组的拆包就是将元组内部的每个元素按照位置一一对应的赋值给不同变量,可以应用到变量赋值,函数参数赋值,获取元组中特定位置的元素值等场合。

  2. namedtuple: 用于存储对象序列,不能改变元素值,可以像dict一样通过名字进行访问,可以通过_asdict()转换为dict,其作用相当于只有属性没有方法的类。

1. 元组的拆包

Python中的元组tuple和列表list类似,不同之处在于元组的元素不能修改,所以被经常称为不可变列表,在形式上,元组用小括号()表示,而列表用中括号[]表示。

元组的拆包就是将元组内部的每个元素按照位置一一对应的赋值给不同变量,比如:

            
              tupleA
              
                =
              
              
                (
              
              
                10
              
              
                ,
              
              
                20.5
              
              
                )
              
              
first
              
                ,
              
              second
              
                =
              
              tupleA 
              
                # 对二元素元组拆包
              
              
                print
              
              
                (
              
              first
              
                )
              
              
                # 10
              
              
                print
              
              
                (
              
              second
              
                )
              
              
                # 20.5
              
              

a
              
                ,
              
              b
              
                ,
              
              c
              
                ,
              
              d
              
                =
              
              
                (
              
              
                'A'
              
              
                ,
              
              
                20.15
              
              
                ,
              
              
                2019
              
              
                ,
              
              
                '10:15:14'
              
              
                )
              
              
                # 多元素元组的拆包
              
              
                print
              
              
                (
              
              a
              
                )
              
              
                # A
              
              
                print
              
              
                (
              
              b
              
                )
              
              
                # 20.15
              
              
                print
              
              
                (
              
              c
              
                )
              
              
                # 2019
              
              
                print
              
              
                (
              
              d
              
                )
              
              
                # 10:15:14
              
            
          

如果拆包应用于上面的简单赋值,那倒是没什么新奇之处。拆包其实被经常用于给函数的参数赋值,比如:

            
              
                def
              
              
                func1
              
              
                (
              
              a
              
                ,
              
              b
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                'a: '
              
              
                ,
              
              a
              
                ,
              
              
                'b: '
              
              
                ,
              
              b
              
                )
              
              
tupleA
              
                =
              
              
                (
              
              
                10
              
              
                ,
              
              
                20.5
              
              
                )
              
              
func1
              
                (
              
              
                *
              
              tupleA
              
                )
              
              
                # 拆包后作为函数的参数,a:  10 b:  20.5
              
            
          

另外一种拆包的应用场景是,某些函数返回一个tuple,而我们需要对其进行拆包,比如:

            
              
                def
              
              
                func2
              
              
                (
              
              x
              
                )
              
              
                :
              
              
                return
              
              
                (
              
              x
              
                ,
              
              x
              
                *
              
              
                2
              
              
                ,
              
              x
              
                *
              
              x
              
                )
              
              
data1
              
                ,
              
              data2
              
                ,
              
              data3
              
                =
              
              func2
              
                (
              
              
                3
              
              
                )
              
              
                print
              
              
                (
              
              data1
              
                )
              
              
                # 3
              
              
                print
              
              
                (
              
              data2
              
                )
              
              
                # 6
              
              
                print
              
              
                (
              
              data3
              
                )
              
              
                # 9
              
            
          

在拆包时,有的元素不是我们所需要的,那就用占位符来代替,即用_代表一个占位符,而*代表多个占位符

            
              data1
              
                ,
              
              _
              
                ,
              
              data3
              
                =
              
              func2
              
                (
              
              
                3
              
              
                )
              
              
                # 用_代表一个变量
              
              
                print
              
              
                (
              
              data1
              
                )
              
              
                # 3
              
              
data1
              
                ,
              
              
                *
              
              rest
              
                =
              
              func2
              
                (
              
              
                3
              
              
                )
              
              
                print
              
              
                (
              
              data1
              
                )
              
              
                # 3
              
              
                print
              
              
                (
              
              rest
              
                )
              
              
                # [6,9]
              
            
          

嵌套元组,顾名思义是元组中包含有元组,对其进行拆包和普通元组的拆包类似。

            
              areas
              
                =
              
              
                [
              
              
                (
              
              
                'hubei'
              
              
                ,
              
              
                'wuhan'
              
              
                ,
              
              
                1200
              
              
                ,
              
              
                (
              
              
                150
              
              
                ,
              
              
                260
              
              
                )
              
              
                )
              
              
                ,
              
              
                (
              
              
                'hunan'
              
              
                ,
              
              
                'changsha'
              
              
                ,
              
              
                3600
              
              
                ,
              
              
                (
              
              
                100
              
              
                ,
              
              
                200
              
              
                )
              
              
                )
              
              
                ,
              
              
                (
              
              
                'shandong'
              
              
                ,
              
              
                'jinan'
              
              
                ,
              
              
                800
              
              
                ,
              
              
                (
              
              
                260
              
              
                ,
              
              
                180
              
              
                )
              
              
                )
              
              
                ]
              
              
                for
              
               province
              
                ,
              
              city
              
                ,
              
              data1
              
                ,
              
              
                (
              
              data2
              
                ,
              
              data3
              
                )
              
              
                in
              
               areas
              
                :
              
              
                print
              
              
                (
              
              
                'P:{}, C:{}, data2:{},data3:{}'
              
              
                .
              
              
                format
              
              
                (
              
              province
              
                ,
              
              city
              
                ,
              
              data2
              
                ,
              
              data3
              
                )
              
              
                )
              
            
          

2. 命名元组

命名元组(namedtuple)类似于tuple,都可以用于存储对象序列,但是它比tuple更加强大,除了延续tuple不能改变元素值这一特性之外,还有其本身的特点,比如可以像dict一样通过名字访问元素值,还可以通过_asdict()转换为dict类型。

命名元组可以构建一个带有字段名的元组和一个有名字的类,其消耗的内存和元组是一样的。

在面向对象的思想下,如果我们需要构建一个简单的类,只是用于存储几个简单的属性,而没有具体的方法,我们可以写成:

            
              
                class
              
              
                PersonCls
              
              
                :
              
              
                # 定义一个类,只有属性,没有具体的方法,用于存储某些属性值
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              name
              
                ,
              
              age
              
                ,
              
              score
              
                )
              
              
                :
              
              
        self
              
                .
              
              name
              
                =
              
              name
        self
              
                .
              
              age
              
                =
              
              age
        self
              
                .
              
              score
              
                =
              
              score
    
              
                def
              
              
                __repr__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                return
              
              
                'PersonCls(name={},age={},score={})'
              
              
                .
              
              
                format
              
              
                (
              
              self
              
                .
              
              name
              
                ,
              
              self
              
                .
              
              age
              
                ,
              
              self
              
                .
              
              score
              
                )
              
              

PC1
              
                =
              
              PersonCls
              
                (
              
              
                'Jack'
              
              
                ,
              
              
                20
              
              
                ,
              
              
                85
              
              
                )
              
              
PC2
              
                =
              
              PersonCls
              
                (
              
              
                'Rose'
              
              
                ,
              
              
                18
              
              
                ,
              
              
                92
              
              
                )
              
              
                print
              
              
                (
              
              PC1
              
                )
              
              
                # PersonCls(name=Jack,age=20,score=85)
              
              
                print
              
              
                (
              
              PC2
              
                )
              
              
                # PersonCls(name=Rose,age=18,score=92)
              
              
                print
              
              
                (
              
              PC1
              
                .
              
              age
              
                )
              
              
                # 20
              
              
                print
              
              
                (
              
              PC2
              
                .
              
              score
              
                )
              
              
                # 92
              
            
          

这样的写法是可行的,但不是Python风格,对这种情况,完全可以交给namedtuple来做,比如,在python里面的写法为:

            
              
                from
              
               collections 
              
                import
              
               namedtuple
Person
              
                =
              
              namedtuple
              
                (
              
              
                'Person'
              
              
                ,
              
              
                [
              
              
                'name'
              
              
                ,
              
              
                'age'
              
              
                ,
              
              
                'score'
              
              
                ]
              
              
                )
              
              
                # 构造一个namedtuple类
              
              

P1
              
                =
              
              Person
              
                (
              
              
                'Jack'
              
              
                ,
              
              
                20
              
              
                ,
              
              
                85
              
              
                )
              
              
                # 构建具体的实例,其赋值顺序要一一对应
              
              
P2
              
                =
              
              Person
              
                (
              
              age
              
                =
              
              
                18
              
              
                ,
              
              name
              
                =
              
              
                'Rose'
              
              
                ,
              
              score
              
                =
              
              
                92
              
              
                )
              
              
                # 如果指定变量名,顺序不用一一对应
              
              
                print
              
              
                (
              
              P1
              
                )
              
              
                # Person(name='Jack', age=20, score=85)
              
              
                print
              
              
                (
              
              P2
              
                )
              
              
                # Person(name='Rose', age=18, score=92)
              
              
                print
              
              
                (
              
              P1
              
                .
              
              age
              
                )
              
              
                # 可以像dict一样通过属性名进行访问
              
              
                print
              
              
                (
              
              P2
              
                .
              
              score
              
                )
              
              
                # 92
              
            
          

上面的 Person=namedtuple('Person',['name', 'age', 'score']) 就相当于构建一个只有属性没有方法的Person类,其属性为:‘name’, ‘age’, ‘score’,代码更加简单,且更有Python味儿。在内存上来说,会比定义一个类要小一些,因为此时不需要用 __dict__ 来存放实例的属性。

命名元组除了从tuple继承来的属性之外,还有其专有属性,最常用的是 _fields, _make(), _asdict() 。如下:

            
              
                # namedtuple专有属性:
              
              
                from
              
               collections 
              
                import
              
               namedtuple
Person
              
                =
              
              namedtuple
              
                (
              
              
                'Person'
              
              
                ,
              
              
                [
              
              
                'name'
              
              
                ,
              
              
                'age'
              
              
                ,
              
              
                'score'
              
              
                ]
              
              
                )
              
              
                print
              
              
                (
              
              Person
              
                .
              
              _fields
              
                )
              
              
                # ('name', 'age', 'score')
              
              
                # _fields属性是一个包含这个类所有属性名称的tuple
              
              

person1
              
                =
              
              
                (
              
              
                'zhangsan'
              
              
                ,
              
              
                25
              
              
                ,
              
              
                59
              
              
                )
              
              
p1
              
                =
              
              Person
              
                .
              
              _make
              
                (
              
              person1
              
                )
              
              
                # _make()接受一个可迭代对象生成一个实例
              
              
                print
              
              
                (
              
              p1
              
                )
              
              
                # Person(name='zhangsan', age=25, score=59)
              
              
                print
              
              
                (
              
              p1
              
                .
              
              _asdict
              
                (
              
              
                )
              
              
                )
              
              
                # OrderedDict([('name', 'zhangsan'), ('age', 25), ('score', 59)])
              
              
                # _asdict()将实例的属性和值以OrderedDict的方式展示出来。
              
            
          

首次发表于: 微信公众号:科技老丁哥,ID: TechDing,敬请关注。

本文所有代码都已经上传到我的github,欢迎下载

参考资料:

  1. 《流畅的Python》,Luciano Ramalho (作者) 安道 , 吴珂 (译者)。

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论