zoukankan      html  css  js  c++  java
  • Python

    为什么要讲解包

    因为我觉得解包是 Python 的一大特性,大大提升了编程的效率,而且适用性很广

    啥是解包

    • 个人通俗理解:解开包袱,拿出东西
    • 正确理解:将元素从可迭代对象中一个个取出来
    • python 中,解包是自动完成的

    最简单的解包栗子

    a, b, c = [1, 2, 3]
    
    print(a, b, c)
    
    
    # 输出结果
    1 2 3 

    列表有 3 个元素,此时也需要 3 个变量去接,否则会报错

    a, b = [1, 2, 3]
    
    
    # 输出结果
        a, b = [1, 2, 3]
    ValueError: too many values to unpack (expected 2)

    太多值无法解包

    重点

    • 除了列表可以解包,任何可迭代对象都支持解包
    • 比如:列表、元组、字典、集合、字符串、生成器,只要实现了 __next__ 方法的对象都是可迭代对象

    可迭代对象详解

    https://www.cnblogs.com/poloyy/p/14658433.html

    各种解包栗子

    元组解包

    >>> a,b,c = (1,2,3)
    >>> a
    1
    >>> b
    2
    >>> c
    3

    字符串解包

    >>> a,b,c = "abc"
    >>> a
    'a'
    >>> b
    'b'
    >>> c
    'c'

    集合解包

    >>> a,b,c = {1,2,3}
    >>> a
    1
    >>> b
    2
    >>> c
    3

    字典解包

    >>> a,b,c = {"a":1, "b":2, "c":3}
    >>> a
    'a'
    >>> b
    'b'
    >>> c
    'c'

    字典解包后,只会把字典的 key 取出来

    多变量赋值

    >>> a, b = 1, 2
    >>> a
    1
    >>> b
    2
    • 其实也是元组解包
    • 元组在 = 右边的时候,可以忽略 ( )

    生成器解包

    # 生成器
    a, b, c = (x + 1 for x in range(3))
    print(a, b, c)
    
    
    # 输出结果
    1 2 3 

    生成器详解文章

    https://www.cnblogs.com/poloyy/p/14664538.html

    解决变量数不等于右侧可迭代对象中元素的个数

    上面提到了这个报错问题

    a, b = [1, 2, 3]
    
    
    # 输出结果
        a, b = [1, 2, 3]
    ValueError: too many values to unpack (expected 2)

    Python3 提供了解决方案

    # 多变量
    a, b, *c = [1, 2, 3, 4, 5]
    print(a, b, c)
    
    
    # 输出结果
    1 2 [3, 4, 5]
    • 在某个变量面前加一个星号
    • 而且这个星号可以放在任意变量
    • 每个变量都分配一个元素后,剩下的元素都分配给这个带星号的变量
    # 多变量
    a, b, *c, d = [1, 2, 3, 4, 5]
    print(a, b, c, d)
    
    
    # 输出结果
    1 2 [3, 4] 5

    函数参数解包

    主要是可变参数、关键字参数

    详解文章:https://www.cnblogs.com/poloyy/p/12526592.html

     

    函数详解文章:https://www.cnblogs.com/poloyy/p/15092393.html

    解包小栗子一

    # 函数
    def test(a, b, c):
        print(a, b, c)
    
    
    # 正常逐个传参
    test(1, 2, 3)
    
    # 只传一个可迭代对象,就需要解包
    test(*[1, 2, 3])
    test(*{1, 2, 3})
    test(*(1, 2, 3))
    
    
    # 输出结果
    1 2 3
    1 2 3
    1 2 3
    1 2 3

    解包小栗子二

    # 函数
    def test(a, b, c):
        print(a, b, c)
    
    
    # 关键字传参
    test(a=1, b=2, c=3)
    
    # 只传一个可迭代对象,就需要解包,和上面写法是等价的
    test(**{"a": 1, "b": 2, "c": 3})
    
    
    # 输出结果
    1 2 3
    1 2 3

    Python 3.5+的新特性

    • 在 3.5 之前,函数调用时,一个函数中解包操作只允许一个 * 和一个 ** 
    • 3.5+ 之后,可以有任意多个解包
    # 函数
    def test(a, b, c, d, e, f):
        print(a, b, c, d, e, f)
    
    
    test(*[1, 2, ], *[3, 4, ], **{"e": 5}, **{"f": 6})
    
    
    # 输出结果
    1 2 3 4 5 6

    在表达式中使用解包

     栗子一

    # 表达式解包
    print(range(3), 3)
    print(*range(3), 3)
    
    print([*range(3), 3])
    
    print({"a": 1, **{"b": 2, "c": 3}})
    
    
    # 输出结果
    range(0, 3) 3
    0 1 2 3
    [0, 1, 2, 3]
    {'a': 1, 'b': 2, 'c': 3}

    栗子二:拼接列表

    # 解包拼接列表
    list1 = [1, 2]
    list2 = range(3, 5)
    list3 = [*list1, *list2]
    print(list3)
    
    
    # 输出结果
    [1, 2, 3, 4]

    list1 可以直接和 list2 做 + 操作吗?

    不行,因为 list 无法与 range() 对象相加

    栗子三:拼接两个字典

    # 解包拼接字典
    dict1 = {"a": 1, "b": 2}
    dict2 = {"name": "yy", "age": 22}
    dict3 = {**dict1, **dict2}
    print(dict3)
    
    
    # 输出结果
    {'a': 1, 'b': 2, 'name': 'yy', 'age': 22}

      

    解包总结

    • 自动解包支持一切可迭代对象
    • 函数调用时,可以用 * 或者 ** 解包可迭代对象

    拓展:Python 函数

    https://www.cnblogs.com/poloyy/p/12526592.html

  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/poloyy/p/15096333.html
Copyright © 2011-2022 走看看