阿咿呀咿呀 發表於 2021-8-4 22:51:00

Python - 解包的各种骚操作

<h3><strong>为什么要讲解包</strong></h3>
<p>因为我觉得解包是 Python 的一大特性,大大提升了编程的效率,而且适用性很广</p>
<p>&nbsp;</p>
<h3><strong>啥是解包</strong></h3>
<ul>
<li>个人通俗理解:解开包袱,拿出东西</li>
<li>正确理解:将元素从可迭代对象中一个个取出来</li>
<li>python 中,解包是自动完成的</li>
</ul>
<p>&nbsp;</p>
<h3><strong>最简单的解包栗子</strong></h3>
<div class="cnblogs_code">
<pre>a, b, c =

</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 3 </pre>
</div>
<p>&nbsp;</p>
<p>列表有 3 个元素,此时也需要 3 个变量去接,否则会报错</p>
<div class="cnblogs_code">
<pre>a, b =


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
    a, b =
ValueError: too many values to unpack (expected </span>2)</pre>
</div>
<p>太多值无法解包</p>
<p>&nbsp;</p>
<h3><strong>重点</strong></h3>
<ul>
<li>除了列表可以解包,任何可迭代对象都支持解包</li>
<li>比如:列表、元组、字典、集合、字符串、生成器,只要实现了 __next__ 方法的对象都是可迭代对象</li>
</ul>
<p>&nbsp;</p>
<h4><strong>可迭代对象详解</strong></h4>
<p>https://www.cnblogs.com/poloyy/p/14658433.html</p>
<p>&nbsp;</p>
<h3><strong>各种解包栗子</strong></h3>
<h4><strong>元组解包</strong></h4>
<div class="cnblogs_code">
<pre>&gt;&gt;&gt; a,b,c = (1,2,3<span style="color: rgba(0, 0, 0, 1)">)
</span>&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> a
</span>1
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> b
</span>2
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> c
</span>3</pre>
</div>
<p>&nbsp;</p>
<h4><strong>字符串解包</strong></h4>
<div class="cnblogs_code">
<pre>&gt;&gt;&gt; a,b,c = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">abc</span><span style="color: rgba(128, 0, 0, 1)">"</span>
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> a
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">'</span>
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> b
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">'</span>
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> c
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">'</span></pre>
</div>
<p>&nbsp;</p>
<h4><strong>集合解包</strong></h4>
<div class="cnblogs_code">
<pre>&gt;&gt;&gt; a,b,c = {1,2,3<span style="color: rgba(0, 0, 0, 1)">}
</span>&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> a
</span>1
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> b
</span>2
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> c
</span>3</pre>
</div>
<p>&nbsp;</p>
<h4><strong>字典解包</strong></h4>
<div class="cnblogs_code">
<pre>&gt;&gt;&gt; a,b,c = {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">"</span>:1, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">"</span>:2, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">"</span>:3<span style="color: rgba(0, 0, 0, 1)">}
</span>&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> a
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">'</span>
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> b
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">'</span>
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> c
</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">'</span></pre>
</div>
<p>字典解包后,只会把字典的 key 取出来</p>
<p>&nbsp;</p>
<h4><strong>多变量赋值</strong></h4>
<div class="cnblogs_code">
<pre>&gt;&gt;&gt; a, b = 1, 2
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> a
</span>1
&gt;&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> b
</span>2</pre>
</div>
<ul>
<li>其实也是元组解包</li>
<li>元组在 = 右边的时候,可以忽略 ( )</li>
</ul>
<p>&nbsp;</p>
<h4><strong>生成器解包</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 生成器</span>
a, b, c = (x + 1 <span style="color: rgba(0, 0, 255, 1)">for</span> x <span style="color: rgba(0, 0, 255, 1)">in</span> range(3<span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 3 </pre>
</div>
<p>&nbsp;</p>
<h4><strong>生成器详解文章</strong></h4>
<p>https://www.cnblogs.com/poloyy/p/14664538.html</p>
<p>&nbsp;</p>
<h3><strong>解决变量数不等于右侧可迭代对象中元素的个数</strong></h3>
<p>上面提到了这个报错问题</p>
<div class="cnblogs_code">
<pre>a, b =


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
    a, b =
ValueError: too many values to unpack (expected </span>2)</pre>
</div>
<p>&nbsp;</p>
<h4><strong>Python3 提供了解决方案</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 多变量</span>
a, b, *c =
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 </pre>
</div>
<ul>
<li>在某个变量面前加一个星号</li>
<li>而且这个星号可以<span style="color: rgba(210, 44, 74, 1)">放在任意变量</span></li>
<li>每个变量都分配一个元素后,剩下的元素都分配给这个带星号的变量</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 多变量</span>
a, b, *c, d =
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c, d)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 5</pre>
</div>
<p>&nbsp;</p>
<h3><strong>函数参数解包</strong></h3>
<p>主要是可变参数、关键字参数</p>
<p>详解文章:https://www.cnblogs.com/poloyy/p/12526592.html</p>
<p>&nbsp;</p>
<p>函数详解文章:https://www.cnblogs.com/poloyy/p/15092393.html</p>
<p>&nbsp;</p>
<h4><strong>解包小栗子一</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 函数</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> test(a, b, c):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 正常逐个传参</span>
test(1, 2, 3<span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 只传一个可迭代对象,就需要解包</span>
test(*)
test(</span>*{1, 2, 3<span style="color: rgba(0, 0, 0, 1)">})
test(</span>*(1, 2, 3<span style="color: rgba(0, 0, 0, 1)">))


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 3
1 2 3
1 2 3
1 2 3</pre>
</div>
<p>&nbsp;</p>
<h4><strong>解包小栗子二</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 函数</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> test(a, b, c):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关键字传参</span>
test(a=1, b=2, c=3<span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 只传一个可迭代对象,就需要解包,和上面写法是等价的</span>
test(**{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 1, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 2, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 3<span style="color: rgba(0, 0, 0, 1)">})


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 3
1 2 3</pre>
</div>
<p>&nbsp;</p>
<h4><strong>Python 3.5+的新特性</strong></h4>
<ul>
<li>在 3.5 之前,函数调用时,一个函数中解包操作只允许一个 * 和一个 **&nbsp;</li>
<li>3.5+ 之后,可以有任意多个解包</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 函数</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> test(a, b, c, d, e, f):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(a, b, c, d, e, f)


test(</span>*, *, **{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">e</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 5}, **{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">f</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 6<span style="color: rgba(0, 0, 0, 1)">})


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
1 2 3 4 5 6</pre>
</div>
<p>&nbsp;</p>
<h3><strong>在表达式中使用解包</strong></h3>
<h4><strong>&nbsp;栗子一</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 表达式解包</span>
<span style="color: rgba(0, 0, 255, 1)">print</span>(range(3), 3<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(*range(3), 3<span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 0, 255, 1)">print</span>([*range(3), 3<span style="color: rgba(0, 0, 0, 1)">])

</span><span style="color: rgba(0, 0, 255, 1)">print</span>({<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 1, **{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 2, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 3<span style="color: rgba(0, 0, 0, 1)">}})


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
range(0, 3) 3<span style="color: rgba(0, 0, 0, 1)">
0 </span>1 2 3<span style="color: rgba(0, 0, 0, 1)">

{</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 1, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 2, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">c</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 3}</pre>
</div>
<p>&nbsp;</p>
<h4><strong>栗子二:拼接列表</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 解包拼接列表</span>
list1 =
list2 </span>= range(3, 5<span style="color: rgba(0, 0, 0, 1)">)
list3 </span>= [*list1, *<span style="color: rgba(0, 0, 0, 1)">list2]
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(list3)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
</pre>
</div>
<p>list1 可以直接和 list2 做 + 操作吗?</p>
<p>不行,因为 list 无法与 range() 对象相加</p>
<p>&nbsp;</p>
<h4><strong>栗子三:拼接两个字典</strong></h4>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 解包拼接字典</span>
dict1 = {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 1, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 2<span style="color: rgba(0, 0, 0, 1)">}
dict2 </span>= {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">yy</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span>: 22<span style="color: rgba(0, 0, 0, 1)">}
dict3 </span>= {**dict1, **<span style="color: rgba(0, 0, 0, 1)">dict2}
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(dict3)


</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 输出结果</span>
{<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 1, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">b</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 2, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yy</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">'</span>: 22}</pre>
</div>
<p>&nbsp;&nbsp;</p>
<h3><strong>解包总结</strong></h3>
<ul>
<li>自动解包支持一切可迭代对象</li>
<li>函数调用时,可以用 * 或者 ** 解包可迭代对象</li>
</ul>
<p>&nbsp;</p>
<h3><strong>拓展:Python 函数</strong></h3>
<p>https://www.cnblogs.com/poloyy/p/12526592.html</p><br><br>
来源:https://www.cnblogs.com/poloyy/p/15096333.html
頁: [1]
查看完整版本: Python - 解包的各种骚操作