Python 拆解包

转自:https://www.jianshu.com/p/22c538a58bcc

python中的解包可以这样理解:一个list是一个整体,想把list中每个元素当成一个个个体剥离出来,这个过程就是解包,我们来看下面这些例子(分为12个部分)。

1.将list中每个元素赋值给一个变量

  1. >>> name, age, date = ['Bob', 20, '2018-1-1']
  2. >>> name
  3. 'Bob'
  4. >>> age
  5. 20
  6. >>> date
  7. '2018-1-1'
  8. 2.可迭代对象都可以这样做
  9. # 列表
  10. >>> a,b,c = ['a', 'b', 'c']
  11. >>> a
  12. 'a'
  13. >>> a,b,c = enumerate(['a', 'b', 'c'])
  14. >>> a
  15. (0, 'a')
  16. # 元组
  17. >>> a,b,c = ('a', 'b', 'c')
  18. >>> a
  19. 'a'
  20. # 字典
  21. >>> a,b,c = {'a':1, 'b':2, 'c':3}
  22. >>> a
  23. 'a'
  24. >>> a,b,c = {'a':1, 'b':2, 'c':3}.items()
  25. >>> a
  26. ('a', 1)
  27. # 字符串
  28. >>> a,b,c = 'abc'
  29. >>> a
  30. 'a'
  31. # 生成器
  32. >>> a,b,c = (x + 1 for x in range(3))
  33. >>> a
  34. 1

如果可迭代对象包含的元素和前面待赋值变量数量不一致,则会报错。但是可以通过*来表示多个元素

3.星号的使用

比如我们要计算平均分,去除最高分和最低分,除了用切片,还可以用解包的方式获得中间的数值

  1. >>> first, *new, last = [94, 85, 73, 46]
  2. >>> new
  3. [85, 73]

用*来表示多个数值

4.压包过程

压包是解包的逆过程,用zip函数实现,下面例子可以对压包有一个直观的感受

  1. >>> a = ['a', 'b', 'c']
  2. >>> b = [1, 2, 3]
  3. >>> for i in zip(a, b):
  4. ... print(i)
  5. ...
  6. ('a', 1)
  7. ('b', 2)
  8. ('c', 3)

5.压包与解包混合的例子

下面例子实现:两个列表对应数值相加

  1. >>> a = [0, 1, 2]
  2. >>> b = [1, 2, 3]
  3. >>> for i, j in zip(a, b):
  4. ... print(i+j)
  5. ...
  6. 1
  7. 3
  8. 5

细细拆解上面过程,可以看出步骤是这样的

先是zip函数将a b压包成为一个可迭代对象

对可迭代对象的每一个元素(('a', 1))进行解包(i, j = ('a', 1))

此时就可以分别调用i j变量进行计算

下面我们加入星号

  1. >>> l = [('Bob', '1990-1-1', 60),
  2. ... ('Mary', '1996-1-4', 50),
  3. ... ('Nancy', '1993-3-1', 55),]
  4. >>> for name, *args in l:
  5. ... print(name, args)
  6. ...
  7. Bob ['1990-1-1', 60]
  8. Mary ['1996-1-4', 50]
  9. Nancy ['1993-3-1', 55]

6._的用法

当一些元素不用时,用_表示是更好的写法,可以让读代码的人知道这个元素是不要的

  1. >>> person = ('Bob', 20, 50, (11, 20, 2000))
  2. >>> name, *_, (*_, year) = person
  3. >>> name
  4. 'Bob'
  5. >>> year
  6. 2000

7.多变量同时赋值

之前赋值符号右侧都是可迭代对象,其实右侧也可以是多个变量

  1. >>> a, b = 1, 2
  2. >>> a
  3. 1
  4. >>> b
  5. 2
  6. >>> a = 1, 2
  7. >>> a

(1, 2)

下面用法都会报错

  1. *a = 1, 2
  2. a, b, c = 1, 2

可以这样

  1. *a, = 1, 2

8.*之可变参数

函数定义时,我们使用*的可变参数,其实也是压包解包过程

  1. >>> def myfun(*num):
  2. ... print(num)
  3. ...
  4. >>> myfun(1,2,5,6)
  5. (1, 2, 5, 6)

参数用*num表示,num变量就可以当成元组调用了。

其实这个过程相当于*num, = 1,2,5,6

9.*之关键字参数

  1. >>> def myfun(**kw):
  2. ... print(kw)
  3. ...
  4. >>> myfun(name = "Bob", age = 20, weight = 50)
  5. {'weight': 50, 'name': 'Bob', 'age': 20}

键值对传入**kw,kw就可以表示相应字典。

**的用法只在函数定义中使用,不能这样使用

  1. a, **b = {'weight': 50, 'name': 'Bob', 'age': 20}

10.可变参数与关键字参数的细节问题

(1)函数传入实参时,可变参数(*)之前的参数不能指定参数名

  1. >>> def myfun(a, *b):
  2. ... print(a)
  3. ... print(b)
  4. ...
  5. >>> myfun(a=1, 2,3,4)
  6. File "<stdin>", line 1
  7. SyntaxError: positional argument follows keyword argument
  8. >>> myfun(1, 2,3,4)
  9. 1
  10. (2, 3, 4)

(2)函数传入实参时,可变参数(*)之后的参数必须指定参数名,否则就会被归到可变参数之中

  1. >>> def myfun(a, *b, c=None):
  2. ... print(a)
  3. ... print(b)
  4. ... print(c)
  5. ...
  6. >>> myfun(1, 2,3,4)
  7. 1
  8. (2, 3, 4)
  9. None
  10. >>> myfun(1, 2,3,c=4)
  11. 1
  12. (2, 3)
  13. 4

如果一个函数想要使用时必须明确指定参数名,可以将所有参数都放在可变参数之后,而可变参数不用管它就可以,也不用命名,如下

  1. >>> def myfun(*, a, b):
  2. ... print(a)
  3. ... print(b)
  4. ...
  5. >>> myfun(a = 1,b = 2)
  6. 1
  7. 2

可变参数的这两条特性,可以用于将 只需要按照位置赋值的参数 和 需要明确指定参数名的参数区分开来

(3)关键字参数都只能作为最后一个参数,前面的参数按照位置赋值还是名称赋值都可以

下面展示一个既用可变参数有用关键字参数的例子

  1. >>> def myfun(a, *b, c, **d):
  2. ... print(a)
  3. ... print(b)
  4. ... print(c)
  5. ... print(d)
  6. ...
  7. >>> myfun(1, 2, 3, c= 4, m = 5, n = 6)
  8. 1
  9. (2, 3)
  10. 4
  11. {'n': 6, 'm': 5}

(4)可变参数与关键词参数共同使用以表示任意参数

下面是这一点在装饰器当中的使用

  1. >>> def mydecorator(func):
  2. ... def wrapper(*args, **kw):
  3. ... print('I am using a decorator.')
  4. ... return func(*args, **kw)
  5. ... return wrapper
  6. ...
  7. >>> @mydecorator
  8. ... def myfun(a, b):
  9. ... print(a)
  10. ... print(b)
  11. ...
  12. >>> myfun(1, b = 2)
  13. I am using a decorator.
  14. 1
  15. 2

(如果有的读者不熟悉装饰器,只需要知道,使用@定义myfun相当于myfun = mydecorator(myfun),定义出来的myfun其实是返回结果wrapper函数)

wrapper函数使用args, **kw作为参数,则被修饰的myfun函数需要的参数无论是什么样的,传入wrapper都不会报错,这保证了装饰器可以修饰各种各样函数的灵活性。毕竟我们一般在函数中传入参数时,要么所有参数名都写,要么前面几个不写,后面的会写,这样使用args, **kw完全没有问题。

11.解包作为参数传入函数中

首先定义一个函数

  1. def myfun(a, b):
  2. print(a + b)

列表元组的解包

  1. >>> n = [1, 2]
  2. >>> myfun(*n)
  3. 3
  4. >>> m = (1, 2)
  5. >>> myfun(*m)
  6. 3

字典的解包

  1. >>> mydict = {'a':1, 'b': 2}
  2. >>> myfun(**mydict)
  3. 3
  4. >>> myfun(*mydict)
  5. ba

一个应用

  1. >>> bob = {'name': 'Bob', 'age': 30}
  2. >>> "{name}'s age is {age}".format(**bob)
  3. "Bob's age is 30"

12.多返回值函数

下面过程也涉及到了解包

  1. def myfun(a, b):
  2. return a + 1, b + 2
  3. >>> m, n = myfun(1, 2)
  4. >>> m
  5. 2
  6. >>> n
  7. 4

其实本身是一个元组

  1. >>> p = myfun(1, 2)
  2. >>> p
  3. (2, 4)

python 拆解包的更多相关文章

  1. 机器学习常用Python扩展包

    在Ubuntu下安装Python模块通常有3种方法:1)使用apt-get:2)使用pip命令(推荐);3)easy_instal 可安装方法参考:[转]linux和windows下安装python集 ...

  2. Python的包管理工具Pip (zz )

    Python的包管理工具Pip 接触了Ruby,发现它有个包管理工具RubyGem很好用,并且有很完备的文档系统http://rdoc.info 发现Python下也有同样的工具,包括easy_ins ...

  3. 简易安装python统计包

    PythonCharm简易安装python统计包及 本文介绍使用pythonCharm IDE 来安装Python统计包或一些packages的简单过程,基本无任何技术难度,顺便提一提笔者在安装过程中 ...

  4. 安装python 的 包 paramiko

    安装python 的 包 paramiko 安装 依赖 yum -y install gcc python-devel 获取安装 pycryptowget https://pypi.python.or ...

  5. python的包和模块

    python 的包即文件夹,但是必须包含_init_.py 模块就是xx.py

  6. Python的包管理

    0.Python的包管理 在刚开始学习Python的时候比较头疼各种包的管理,后来搜到一些Python的包管理工具,比如setuptools, easy_install, pip, distribut ...

  7. Python机器学习包

    常用Python机器学习包 Numpy:用于科学计算的包 Pandas:提供高性能,易于使用的数据结构和数据分析工具 Scipy:用于数学,科学工程的软件 StatsModels:用于探索数据.估计统 ...

  8. python 子包引用父包和其他子包

    python 子包引用父包和其他子包 python引用子目录很简单, 里面放个__init__.py就可以了. 如何在子目录里面引用其他目录(父目录,爷目录和同辈分目录)呢? 例如: python有项 ...

  9. 关于Python 解包,你需要知道的一切

    解包在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来(防杠精:此处描述并不严谨,因为容器中的元素并没有发生改变)放在其它地方,好比你老婆去菜市场买了一袋苹果回来分别发给家里的每个成员, ...

随机推荐

  1. kali下DNS劫持(9.28 第十四天)

    DNS劫持 环境: windows2008R2    被攻击者 kali        攻击者 1.在攻击者电脑中搭建web服务 2.在/var/www/html 写入html文件 index.htm ...

  2. css常用技巧1

    css绘制三角形 <style> .triangle-box{ margin: 50px auto; height: 300px; width: 500px; box-shadow: 1p ...

  3. 大二暑假第三周总结--开始学习Hadoop基础(二)

    简单学习NoSQL数据库理论知识 NoSQL数据库具有以下几个特点: 1.灵活的可扩展性(支持在多个节点上进行水平扩张) 2.灵活的数据模型(与关系数据库中严格的关系模型相反,显得较为松散) 3.与与 ...

  4. iOS应用内跳转到指定系统设置页

    APP的跳转: 通过[ [UIApplication sharedApplication] openURL:url]这种方法来实现的. iOS 10以后跳转设置页要用 [[UIApplication ...

  5. String类型不属于八种基本类型

    String不属于8种基本数据类型,String是一个对象.因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. new String( ...

  6. centos 7.4 安装docker 19.03.6 版本。附带离线安装包

    说明: 1.此环境为未安装过docker服务的环境, 如果已经安装,则自行卸载. 2.以下环境中上传的包及离线yum源默认为/home目录下,如无特殊说明,以此目录为准 步骤一:下载docker离线安 ...

  7. Zxing和QR Code生成和解析二维码

    本文是学习慕课网课程<Java生成二维码>(http://www.imooc.com/learn/531)的笔记. 一.二维码的分类 线性堆叠式二维码.矩阵式二维码.邮政码. 二.二维码的 ...

  8. iOS 修改默认 UserAgent

    User-Agent(用户代理)字符串是Web浏览器用于声明自身型号版本并随HTTP请求发送给Web服务器的字符串,在Web服务器上可以获取到该字符串. UIWebView修改UserAgent UI ...

  9. 201709-1 打酱油 Java

    思路: 先看能不能买5瓶,因为送的最多,然后看能不能买3瓶,最后一瓶一瓶地买 import java.util.Scanner; public class Main { public static v ...

  10. ssh到ubuntu没颜色

    ssh远程到ubuntu系统, 没有颜色. 原因是 .bashrc 配置没生效. $ echo '. $HOME/.bashrc' > ~/.profile