[小白自学python]如何理解与应用装包与解包?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[小白自学python]如何理解与应用装包与解包?相关的知识,希望对你有一定的参考价值。
*args/**kwargs/*[1,100]
求大佬指导一下类中/方法中 如何理解与应用装包与解包
我们把一个事物进行分解,就可以得到其中的元素。对于python中的解包来说,也是同样的使用,相信大家从名称就可以观察出来了。那么在具体的解包过程中,关于具体的操作方法想必大家还是不清楚的。下面我们就python解包的概念、注意点进行讲解,然后带来一个解包的实例。
1、概念
解包就是把一个容器拆开、分解,在Python中的解包是自动完成的。
变量数量 = 元素数量,会进行逐一赋值。
2、注意
(1)自动解包支持一切可迭代对象。
(2)python3中,支持更高级的解包操作,用星号操作使得等号左边的变量个数可以少于右边迭代对象中元素的个数。
(3)函数调用时,可以用*或者**解包可迭代对象,作为参数传递。
(4)python3.5,函数调用和表达式中可支持更多的解包操作。
3、实例
一个list是一个整体,想把list中每个元素当成个体剥离出来。
>>> name, age, date = ['Bob', 20, '2018-1-1']
>>> name'Bob'
>>> age20
>>> date'2018-1-1'2.可迭代对象都可以这样做# 列表
>>> a,b,c = ['a', 'b', 'c']
>>> a'a'
>>> a,b,c = enumerate(['a', 'b', 'c'])
>>> a(0, 'a')# 元组
>>> a,b,c = ('a', 'b', 'c')
>>> a'a'# 字典
>>> a,b,c = 'a':1, 'b':2, 'c':3
>>> a'a'>>> a,b,c = 'a':1, 'b':2, 'c':3.items()
>>> a('a', 1)# 字符串
>>> a,b,c = 'abc'
>>> a'a'# 生成器
>>> a,b,c = (x + 1 for x in range(3))
>>> a1
知识点扩展:
解包
在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来放在其它地方,好比你父母去菜市场买了一袋苹果回来分别发给家里的每个成员,这个过程就是解包。Python 中的解包是自动完成的,例如:
student = ['weix','mengy','7762']name,sex,age = studentprint(name,sex,age)
结果:weix meng 7762
如果列表中有3个元素,那么刚好可以分配给3个变量。除了列表对象可以解包之外,任何可迭代对象都支持解包,可迭代对象包括元组、字典、集合、字符串、生成器等实现了__next__方法的一切对象。这里还是要推荐下小编的Python学习喂鑫*(同音):‘’七六二,四五九,五一零‘’不管你是小白还是大牛,小编我都欢迎,不定期分享干货,包括小编自己整理的一份2021最新的Python资料和0基础入门教程,欢迎初学和进阶中的小伙伴。在不忙的时间我会给大家解惑。
到此这篇关于python解包概念及实例的文章就介绍到这了
*args和 **kwargs是常用的两个参数
*args:用于接受多余的未命名的参数,元组类型。
**kwargs:用于接受形参的命名参数,字典类型的数据。
可变参数args:
def fun(n, *args):
print(n)
print(args) # 未拆包
print(*args) # 进行拆包
fun(1,2,3,4)
结果:
1
(2, 3, 4)
2 3 4
形参中的*args是接受数据的args,它是一个元组,把传入的数据放进args元组中。
函数中的args仍然是元组, *args就是将元组的数据进行拆包,一开始输入的形式。
关键字参数**kwargs
def fun(**kwargs):
print(kwargs) # 未拆包
print(*kwargs) # 进行拆包
fun(a=1, b=2)
结果:
'a': 1, 'b': 2
a b
*args用来接受多余的未命名参数, **kwargs是用来接受命名参数。
装包的意义就是把未命名的参数和命名的参数放在元组或字典中。
解包
上面介绍了args, kwargs的装包作用,起到作用的是、 这两个参数。
1. 解包的意义就是将传递给函数的一个列表,元组,字典,拆分成独立的多个元素然后赋值给函数中的参变量。
2. 解压字典有两种解发,一种用*解的只有key,一种用**解的有key,value。但是这个方法**只能在函数定义中使用。
def fun(*args, **kwargs):
for arg in args:
print(arg)
for k, v in kwargs.items():
print(k, v)
print('-'*50)
fun(a, c) # 参数都赋值给args,并没有kwargs的参数
fun(*a, *c) # 解压的参数都赋值给args 等价为 1, 2, 3, 'a', 'b', 'c'
fun(*a, **c) # a解压给args,c解压给kwargs 等价为 1, 2, 3, 'a'=1, 'b'=2, 'c'=3
结果:
[1, 2, 3]
'a': 1, 'b': 2, 'c': 3
--------------------------------------------------
a
b
c
--------------------------------------------------
a 1
b 2
c 3
问题:
在传入参数时,可变参数(*)之前不能指定参数名
def myfun(a, *b):
print(a)
print(b)
myfun(a=1,2,3,4)
myfun(a=1,2,3,4)
^
SyntaxError: positional argument follows keyword argument
2.函数传入实参时,可变参数(*)之后的参数必须指定参数名,否则就会被归到可变参数之中
def myfun(a, *b, c=None):
print(a)
print(b)
print(c)
myfun(1,2,3,c=4)
(2, 3)
.一个函数想要使用时必须明确指定参数名,可以将所有参数都放在可变参数之后
def myfun(*, a, b):
print(a)
print(b)
myfun(a=1, b=2)
4.关键字参数都只能作为最后一个参数,前面的参数按照位置赋值还是名称赋值都可以
def myfun(a, *b, c, **d):
print(a)
print(b)
print(c)
print(d)
myfun(1, 2, w=6, c=3, d=4, e=5) # 记住可变参数(*)之前不能指定参数名
(2,)
'w': 6, 'd': 4, 'e': 5
以上这篇对python中的装包与解包实例详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小编。本回答被提问者和网友采纳
返回类型推论与解包引用的混淆
【中文标题】返回类型推论与解包引用的混淆【英文标题】:Confusion on return type deduction with unpacking references 【发布时间】:2022-01-21 23:50:50 【问题描述】:以下代码
#include <functional>
#include <tuple>
#include <iostream>
struct Point
int x;
int y;
;
decltype(auto) memrefs(Point &p)
return std::make_tuple(std::ref(p.x), std::ref(p.y));
int main()
Point p;
auto& [x, y] = memrefs(p);
x = 1;
y = 2;
std::cout << p.x << " " << p.y << std::endl;
return 0;
不编译。由 GCC 8.1.0 报告:
错误:无法将'std::tuple
&'类型的非常量左值引用绑定到'std::tuple '类型的右值
但是,如果我改变它会编译
auto& [x, y] = memrefs(p);
到
auto [x, y] = memrefs(p)
我的问题是为什么? x
和 y
不是引用吗?
【问题讨论】:
decltype(auto) memrefs(Point &p)
返回一个临时值,即右值。右值只能绑定const &
,或者在您的第二种情况下复制。
您在寻找std::tie
吗?
感谢您的回复。现在对我来说有点道理。我无法理解当返回单个引用时必须使用 auto& x = getref();
而不是返回多个引用时这一事实。
【参考方案1】:
decltype(auto) memrefs(Point &p);
是
std::tuple<int&, int&> memrefs(Point &p);
在structured_binding,
auto&
in auto& [x, y]
适用于 "tuple",不适用于 x
、y
。
你不能拥有
std::tuple<int&, int&>& tup = memrefs(p);
但你可以拥有
std::tuple<int&, int&> tup = memrefs(p);
那么x
、y
指的是元组的适当部分。
【讨论】:
【参考方案2】:线
return std::make_tuple(std::ref(p.x), std::ref(p.y));
正在构造一个std::tuple<int&, int&>
类型的临时局部变量并将其作为右值返回。在这种情况下,作为一个临时变量,它可以通过 const 引用 (const std::tuple<int&, int&>&
) 获取,也可以复制到新的元组 (std::tuple<int&, int&>
) 中。在您的情况下,您试图获取对临时对象的非 const 引用 (std::tuple <int&, int&>&
),这是不允许的。
您如何指出,解决方案是将memrefs
返回的值复制到一个新值中,或者使用 const 引用获取它。
【讨论】:
我同意你的观点,但是pastebin.com/8p6JY7fb 它打印出 std::tuplestd::make_tuple
处理 std::reference_wrapper
以使用参考。
@Jarod42 所以简而言之,我和int&
是对的?以上是关于[小白自学python]如何理解与应用装包与解包?的主要内容,如果未能解决你的问题,请参考以下文章