Python的 解構 與 集合

解構與封裝

1、解構

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]:

解構:按元素順序,把線性結構的元素,賦值給變量javascript

2、封裝

In [10]: t = 1, 2

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

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

In [13]:

封裝:定義一個元組,能夠忽略小括號,封裝出來的必定是元組java

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

3、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 的合法標識符,可是若是不是要丟棄一個變量,一般不要用單個下劃線表示一個有意義的變量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

集 合

1、定義

數學意義上的集合:沒有重複元素express

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

2、增長

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]:

3、刪除

一、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]:

二、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]:

三、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]:

四、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      清空集合

4、修改

集合不能修改單個元素bash

 

5、查找

集合不能經過索引訪問,由於集合不是一個線性結構app

集合沒有訪問單個元素的方法oop

集合不是線性結構, 集合元素沒有順序ui

 

成員運算符

  • in
  • not in

判斷一個元素,是否在容器中spa

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]:

集合的成員運算 和 其餘線性結構的時間複雜度是不一樣的code

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)

我的經驗,集合能夠用於去重

相關文章
相關標籤/搜索