Python的 解构 与 集合

匆匆过客 提交于 2019-12-21 11:26:05

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

解构与封装

一、解构

In [1]: x = 1

In [2]: y = 2

In [3]: x, y = y, x   # Python 的解构

In [4]: print(x, y)
2 1

In [5]: lst = [1, 2]

In [6]: first = lst[0]

In [7]: second = lst[1]

In [8]: first, second = lst

In [9]: print(first, second)
1 2

In [10]: 

解构:按元素顺序,把线性结构的元素,赋值给变量

二、封装

In [10]: t = 1, 2

In [11]: t
Out[11]: (1, 2)

In [12]: type(t)
Out[12]: tuple

In [13]: 

封装:定义一个元组,可以忽略小括号,封装出来的一定是元组

In [21]: t = 1, 2

In [22]: t
Out[22]: (1, 2)

In [23]: t1 = 1, 2

In [24]: t2 = (1, 2)

In [25]: t1 == t2
Out[25]: True

In [26]: t1 is t2
Out[26]: False

三、Python3 中的解构变化

In [1]: lst = list(range(1000))

In [2]: head, *mid, tail = lst  # 通过使用星号 * 加上变量,可以接受 所有变量

In [3]: head
Out[3]: 0

In [4]: mid
Out[4]: 
[1,
 2,
 3,
 4,
 5,
 6
...
 
 996,
 997,
 998]

In [5]: tail
Out[5]: 999

In [6]: *mid
  File "<ipython-input-6-bad835e70ef0>", line 1
    *mid
        ^
SyntaxError: can't use starred expression here


In [7]: head, *tail = lst   # *tail 代表的是 除了第一个元素之外的 所有元素

In [8]: head
Out[8]: 0

In [9]: tail
Out[9]: 
[1,
 2,
 3,
 4,
 5,
 6,
 ...

 996,
 997,
 998,
 999]

In [10]: 
In [10]: lst = [0, 1, 2, 3, 4]

In [11]: *head tail = lst    # *head 代表除了最后一个元素外的所有元素
  File "<ipython-input-11-d740de60225c>", line 1
    *head tail = lst
             ^
SyntaxError: invalid syntax


In [12]: lst = [0, 1, 2, 3, 4]

In [13]: *head, tail = lst 

In [14]: head
Out[14]: [0, 1, 2, 3]

In [15]: *lst2 = lst  # 不能单一的使用星号作为变量接收, 如果可以,相当于lst[0:0]
  File "<ipython-input-15-419bc512b767>", line 1
    *lst2 = lst
               ^
SyntaxError: starred assignment target must be in a list or tuple


In [16]: head *m1, *m2, tail = lst   # 同一个解构中,只能使用一个星号 *
  File "<ipython-input-16-6a6d2cc4b0f7>", line 1
    head *m1, *m2, tail = lst
                             ^
SyntaxError: can't assign to operator


In [17]: 
In [2]: lst = [0, 1, 2, 3, 4]

In [3]: *head, tail = lst

In [4]: head
Out[4]: [0, 1, 2, 3]

In [5]: first, second, *others, last = lst 

In [6]: print(first, second, others, last)
0 1 [2, 3] 4

In [7]: v1, v2, v3, v4, v5, v6, v7 = lst  # 当左边变量超过右边元素个数的时候,是不允许的
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-af83bc79cde9> in <module>()
----> 1 v1, v2, v3, v4, v5, v6, v7 = lst

ValueError: not enough values to unpack (expected 7, got 5)

In [8]: v1, v2 = lst             # 数量不匹配
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-881bb3bee854> in <module>()
----> 1 v1, v2 = lst
  • 元素按照顺序赋值给变量
  • 变量个数 和 元素个数必须匹配
  • 加星号变量, 可以接受任意个数的元素
  • 加星号的变量不能单独出现
In [9]: f, *t = (1, 2, 3, 4)

In [10]: f
Out[10]: 1

In [11]: t                          # 无论右边元素是什么类型, 左边的星号变量都是列表
Out[11]: [2, 3, 4]


In [16]: lst
Out[16]: [0, 1, 2, 3, 4]

In [17]: head, *_, tail = lst       # 在Python中, 使用下划线_的方式 来丢弃该变量

In [18]: _
Out[18]: [1, 2, 3]

In [19]: 
In [20]: for i, _ in enumerate(l):
    ...:     print(i)
    ...:     
0
1

In [21]: 

 

单个下划线 是python 的合法标识符,但是如果不是要丢弃一个变量,通常不要用单个下划线表示一个有意义的变量

# 如何取出索引1, 3, 倒数第二个数
In [1]: lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: _, v1, _, v2, *_, last, _ = lst

In [3]: v1
Out[3]: 2

In [4]: v2
Out[4]: 4

In [5]: last
Out[5]: 8

In [6]: 
In [6]: lst = [1, (2, 3), 5]

In [7]: _, v, *_ = lst

In [8]: v
Out[8]: (2, 3)

In [9]: _, val = v

In [10]: val
Out[10]: 3

In [11]: _, (*_, tail), *_ = lst  # 解构是支持多层次的

In [12]: tail
Out[12]: 3

In [13]: _, [*_, tail], *_ = lst

In [14]: tail
Out[14]: 3

集 合

一、定义

数学意义上的集合:没有重复元素


In [1]: s = set()    # set 是一个无序的集合

In [2]: s
Out[2]: set()

In [3]: s = {1, 2, 3}

In [4]: s
Out[4]: {1, 2, 3}

In [5]: type(s)
Out[5]: set

In [6]: s = set(range(3))

In [7]: type(s)
Out[7]: set

二、增加

In [8]: s
Out[8]: {0, 1, 2}

In [9]: s.add(3)               # 通过 add 的方法对集合进行添加元素

In [10]: s
Out[10]: {0, 1, 2, 3}
In [11]: help(s.update)

Help on built-in function update:

update(...) method of builtins.set instance
    Update a set with the union of itself and others.
~
(END)
In [12]: s
Out[12]: {0, 1, 2, 3}

In [13]: s.update(range(8,10))  # update 方法 原地修改,返回None, update 方法是对可迭代对象进行操作

In [14]: s
Out[14]: {0, 1, 2, 3, 8, 9}

In [15]: s.update(range(4, 10))

In [16]: s
Out[16]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}


In [20]: for e in range(10):
    ...:     s.add(e)
    ...:     print(e)
    ...:     
0
1
2
3
4
5
6
7
8
9

In [21]: 

三、删除

1、s.remove()

In [22]: s
Out[22]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In [23]: s.remove(6)

In [24]: s
Out[24]: {0, 1, 2, 3, 4, 5, 7, 8, 9}

In [25]: s.remove(6)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-25-077f15baad77> in <module>()
----> 1 s.remove(6)

KeyError: 6

In [26]: s.remove(999)  # remove方法 删除一个set 中的元素;若元素不存在,则抛出KeyError
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-26-5cd7a055ca70> in <module>()
----> 1 s.remove(999)

KeyError: 999

In [27]: 

2、s.pop()

In [27]: help(s.pop)
pop(...) method of builtins.set instance
    Remove and return an arbitrary set element.
    Raises KeyError if the set is empty.

~
(END)
In [2]: s = set(range(10))

In [3]: s
Out[3]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

In [4]: s.pop()
Out[4]: 0

In [5]: s
Out[5]: {1, 2, 3, 4, 5, 6, 7, 8, 9}

In [6]: lst = [1, (2, 3), 5]

In [7]: lst.pop()
Out[7]: 5

In [8]: lst
Out[8]: [1, (2, 3)]

In [9]: lst.pop()
Out[9]: (2, 3)

In [10]: s = {'a', 1, 'b',-1}

In [11]: s
Out[11]: {-1, 1, 'a', 'b'}

In [12]: s.pop()
Out[12]: 'a'

In [13]: s.pop()
Out[13]: 1

In [14]: s.pop()
Out[14]: 'b'

In [15]: s.pop()
Out[15]: -1

In [16]: s.pop() # s.pop() 随机删除s中一个元素,若集合s为空,则抛出 KeyError
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-16-c88c8c48122b> in <module>()
----> 1 s.pop()

KeyError: 'pop from an empty set'

In [17]: 

3、s.clear()

In [17]: s
Out[17]: set()

In [18]: s = {'a', 1, 'b',-1}

In [19]: s.clear()

In [20]: s
Out[20]: set()

In [21]: 

4、s.discard()


In [21]: help(s.discard) 
Help on built-in function discard:

discard(...) method of builtins.set instance
    Remove an element from a set if it is a member.
    
    If the element is not a member, do nothing.
~

(END)
In [23]: s = {1, 2}

In [24]: s.discard(1)

In [25]: s
Out[25]: {2}

In [26]: s.discard(2)

In [27]: s
Out[27]: set()

In [28]: s.discard(1)

In [29]: s.discard(999)  #  discard 并不会报错

In [30]: 
  • remove 删除给定的元素, 若元素不存在,抛出KeyError
  • discard  删除给定的元素,若元素不存在,什么也不做
  • pop        随机删除一个元素并返回,集合为空时,抛出KeyError
  • clear      清空集合

四、修改

集合不能修改单个元素

 

五、查找

集合不能通过索引访问,因为集合不是一个线性结构

集合没有访问单个元素的方法

集合不是线性结构, 集合元素没有顺序

 

成员运算符

  • in
  • not in

判断一个元素,是否在容器中

In [30]: 3 in [1, 2, 3, 4]
Out[30]: True

In [31]: 10 in [1, 2, 3, 4]
Out[31]: False

In [32]: 10 not in [1, 2, 3, 4]
Out[32]: True

In [33]: 'a' in 'i love miracle'
Out[33]: True

In [34]: 'i' not in 'apple'
Out[34]: True

In [35]: 1 in 1   # 这里第二个 1 不是一个容器
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-35-ca0393ac6151> in <module>()
----> 1 1 in 1

TypeError: argument of type 'int' is not iterable

In [36]: b'b' in bytearray(b'abc')
Out[36]: True

In [37]: 

集合的成员运算 和 其他线性结构的时间复杂度是不同的

In [41]: lst = list(range(1000000))

In [42]: s = set(range(1000000))

In [43]: %%timeit
    ...: -1 in lst
    ...: 
8.61 ms ± 37.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [44]: %%timeit
    ...: -1 in s
    ...: 
32.4 ns ± 0.219 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [45]: 

能够使用set 做成员运算的时候,尽量使用集合,而不要使用list,tuple等线性结构。

  • 集合的效率 和 集合的规模无关,O(1)
  • 列表的效率 和 列表的规模成正比,O(n)

个人经验,集合可以用于去重

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!