[ Python ] set集合及函數的使用

1. set類型

set 和 dict 相似,也是一組 key 的集合,可是不存儲 value. 因爲 key  不重複,因此,在 set 中, 沒有重複的 key 集合是可變類型python

(1)集合的建立app

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一種方式建立 set 類型
>>>  print ( type (set1), set1)
< class  'set' > { 1 3 6 'z' 'a' 'b' }
 
# 第二種方式建立 set 類型
>>> set2  =  set ([ 'z' 'a' 'b' 3 6 1 ])
>>>  print ( type (set2), set2)
< class  'set' > { 1 3 6 'z' 'a' 'b' }
 
# 第三種方式建立 set 類型
>>> set3  =  set ( 'hello' )
>>>  print ( type (set3), set3)
< class  'set' > { 'o' 'e' 'l' 'h' }

 

2. set 工廠函數

(1)add(self, *args, **kwargs)函數

  新增一個元素到集合優化

1
2
3
4
5
6
7
set1  =  { 'a' 'z' 'b' 4 6 1 }
set1.add( 8 )
set1.add( 'hello' )
print (set1)
 
# 執行結果:
# {'b', 1, 'a', 4, 6, 8, 'hello', 'z'}

 

(2) clear()
  清空全部集合元素spa

1
2
3
4
5
6
set1  =  { 'a' 'z' 'b' 4 6 1 }
set1.clear()
print (set1)
 
# 執行結果:
# set()

 

(3)copy()
    拷貝整個集合並賦值給變量code

1
2
3
4
5
6
set1  =  { 'a' 'z' 'b' 4 6 1 }
set2  = set1.copy()
print (set2)
 
# 執行結果:
# {1, 'a', 4, 6, 'b', 'z'}

 

(4)pop()
    隨機刪除集合中一個元素,能夠經過變量來獲取刪除的元素對象

1
2
3
4
5
6
7
8
set1  =  { 'a' 'z' 'b' 4 6 1 }
ys  =  set1.pop()
print ( 'set1集合:' , set1)
print ( '刪除的元素:' , ys)
 
# 執行結果:
# set1集合: {4, 6, 'z', 'a', 'b'}
# 刪除的元素: 1

 

(5)remove(self, *args, **kwargs)
    刪除集合中指定的元素,若是該集合內沒有該元素就報錯blog

1
2
3
4
5
6
7
8
9
10
11
12
set1  =  { 'a' 'z' 'b' 4 6 1 }
set1.remove( 'a' )
print (set1)
set1.remove( 'x' )
print (set1)
 
# 執行結果:
# {1, 4, 6, 'b', 'z'}
# Traceback (most recent call last):
#   File "D:/learn_python/learn_python/day13/s1.py", line 43, in <module>
#     set1.remove('x')
# KeyError: 'x'

 

(6)discard(self, *args, **kwargs)
    刪除集合中指定的元素,若是該集合內沒有該元素也不會報錯遞歸

1
2
3
4
5
6
7
8
9
set1  =  { 'a' 'z' 'b' 4 6 1 }
set1.discard( 'a' )
print (set1)
set1.discard( 'y' )
print (set1)
 
# 執行結果:
# {1, 4, 6, 'b', 'z'}
# {1, 4, 6, 'b', 'z'}

 

pop() 、remove() 、 discard() 三個集合刪除函數比較:
    pop() 隨機刪除集合中一個元素remove() 刪除集合中指定的元素,若是集合中沒有指定的元素,程序報錯!
    discard() 刪除集合中指定的元素,若是集合中沒有指定的元素,程序正常運行。ci

 

(7) intersection  & :交集; union | :並集合; difference - : 差集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
set1  =  { 'a' 'b' 'x' 'y' }
set2  =  { 'i' 'j' 'b' 'a' }
 
# 交集
print (set1 & set2)
print (set1.intersection(set2))
 
# 執行結果:
# {'a', 'b'}
# {'a', 'b'}
 
 
# 並集
print (set1 | set2)
print (set1.union(set2))
 
# 執行結果:
# {'y', 'j', 'a', 'b', 'x', 'i'}
# {'y', 'j', 'a', 'b', 'x', 'i'}
 
# 差集
print (set1  -  set2)
print (set1.difference(set2))
print (set2  -  set1)
print (set2.difference(set1))
 
# 執行結果:
# {'y', 'x'}
# {'y', 'x'}
# {'j', 'i'}
# {'j', 'i'}

 

(8)difference_update ()
    求差集,並賦值給源集合

1
2
3
4
5
6
7
set1  =  { 'a' 'b' 'x' 'y' }
set2  =  { 'i' 'j' 'b' 'a' }
set1.difference_update(set2)
print (set1)
 
# 執行結果:
# {'y', 'x'}

 

(9)intersection_update()
    求交集,並賦值給源集合

1
2
3
4
5
6
7
8
set1  =  { 'a' 'b' 'x' 'y' }
set2  =  { 'i' 'j' 'b' 'a' }
 
set1.intersection_update(set2)
print (set1)
 
# 執行結果:
# {'b', 'a'}

 

(10)symmetric_difference()  和 ^ 符號效果同樣
    求交叉補集

1
2
3
4
5
6
7
8
9
set1  =  { 'a' 'b' 'x' 'y' }
set2  =  { 'i' 'j' 'b' 'a' }
 
print ( 'symmetric_difference:' , set1.symmetric_difference(set2))
print ( '^:' , set1 ^ set2)
 
# 執行結果:
# symmetric_difference: {'x', 'i', 'y', 'j'}
# ^: {'x', 'i', 'y', 'j'}

 

(11)symmetric_difference_update()
  求交叉補集並賦值給源集合

1
2
3
4
5
6
7
8
set1  =  { 'a' 'b' 'x' 'y' }
set2  =  { 'i' 'j' 'b' 'a' }
 
set1.symmetric_difference_update(set2)
print (set1)
 
# 執行結果:
# {'y', 'i', 'j', 'x'}

 

(12)update()
    更新集合,參數爲可迭代對象

1
2
3
4
5
6
7
set1  =  { 'a' 'b' 'x' 'y' }
 
set1.update(( 'hello' 'world' ))
print (set1)
 
# 執行結果:
# {'hello', 'world', 'b', 'a', 'y', 'x'}

 

add() 和 update() 比較:
    add(): 只能添加一個元素到集合
    update(): 能夠添加多個元素到集合,參數爲 iterable

 

使用 frozenset 定義不可變集合

1
2
3
4
5
=  frozenset ( 'hello' )
print (s)
 
# 執行結果:
# frozenset({'h', 'e', 'o', 'l'})

 使用 frozenset 定義的集合,沒有 add 或者 pop 等方法

 

3. 函數

(1)函數表現形式
python中函數的定義方法:

1
2
3
4
def  test(x):
         "The function definitions"
         + =  1
         return  x

 

def: 定義函數關鍵字
test: 函數名(): 內可定義參數"": 文檔描述(非必要,強烈建議添加函數信息描述)
x+=1 : 泛指代碼塊或程序處理邏輯
return: 定義返回值

調用運行:能夠帶參數也能夠不帶函數名()

使用函數的好處:
    代碼重用
    保持一致性,易維護
    可擴展

函數返回值:
    返回值 = 0 : 返回 None
    返回值 = 1 : 返回 object
    返回值數 > 1: 返回 tuple

 

(2)函數的參數

建議參考:廖老師python3函數的參數

 

4. 全局變量和局部變量

若是函數的內容無 global 關鍵字,優先讀取局部變量,能讀取全局變量,沒法對全局變量從新賦值 NAME='FFF',可是對於可變類型,能夠對內部元素進行操做;
若是函數中有 global 關鍵字,變量本質上就是全局變量,可讀取可賦值 NAME='fff'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
name  =  'hkey'
 
def  test1():
         name  =  'xiaofei'
         print (name)
 
def  test2():
         global  name
         name  =  'xxxx'
 
test1()
test2()
print ( 'name:' , name)
 
# 執行結果:
# xiaofei
# name: xxxx

 

 

若是函數內無 global 關鍵字:

    (1)有聲明局部變量

1
2
3
4
5
6
7
8
9
10
NAME  =  [ 'xiaofei' 'hkey' ]
 
def  test():
         NAME  =  'sky'
         print ( 'name:' , NAME)
 
test()
 
# 執行結果:
# name: sky

 

    (2)無聲明局部變量
    對於可變類型,能夠對內部元素進行操做;

1
2
3
4
5
6
7
8
9
10
NAME  =  [ 'xiaofei' 'hkey' ]
 
def  test():
         NAME.append( 'sky' )
         print ( 'name:' , NAME)
 
test()
 
# 執行結果:
# name: ['xiaofei', 'hkey', 'sky']

 

若是函數內有 global 關鍵字

    (1)有聲明局部變量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NAME  =  [ 'xiaofei' 'hkey' ]
 
def  test():
         # 獲取全局變量 NAME
         global  NAME
         # 打印全局變量 NAME
         print ( 'global NAME:' , NAME)
         # 將全局變量 NAME 修改成 'test_func'
         NAME  =  'test_func'
         # 打印修改後的全局變量
         print ( 'name:' , NAME)
 
test()
 
# 執行結果:
# global NAME: ['xiaofei', 'hkey']

 

    (2)無聲明局部變量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NAME  =  [ 'xiaofei' 'hkey' ]
 
def  test():
         # 獲取全局變量 NAME
         global  NAME
         # 打印全局變量 NAME
         print (NAME)
         # 修改全局變量爲 ['sky']
         NAME  =  [ 'sky' ]
         # 追加全局變量
         NAME.append( 'blue' )
         # 打印修改後的全局變量
         print (NAME)
 
test()
 
# 執行結果:
##['sky','blue']

 

在代碼中咱們規定,全局變量名所有使用大寫,而局部變量用小寫,這邊就避免變量名的混淆;

    (3)nonlocal 關鍵字用來在函數或者其餘做用域中使用外層變量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def  outer():
         num  =  10
         def  inner():
                 nonlocal num     # nonlocal 關鍵字聲明
                 num  =  100        # 修改做用域 num 使用方法和 global 一致
                 print (num)     
         inner()
         print (num)           # 該 num 已經在 inner() 中修改過的
 
outer()
 
# 執行結果:
# 100
# 100

 

 5. 遞歸函數

   (1)函數即變量

1
2
3
4
5
6
7
8
def  test():
         pass
 
=  test     # 把函數看成值 賦值給變量 t
print (t)
 
# 執行結果:
# <function test at 0x00000245A2FBA048>

   

  (2)遞歸函數

      在函數內部,能夠調用其餘函數。若是一個函數在內部調用自身自己,這個函數就是遞歸函數。
      遞歸函數的優勢是定義簡單,邏輯清晰。理論上,全部的遞歸函數都寫成循環的方式,但循環的邏輯不如遞歸清晰。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def  fact(n):
         if  = =  1 :
                 return  1
         return  *  fact(n  -  1 )
 
print (fact( 5 ))
 
# 執行過程以下:
#
# ===> fact(5)
# ===> 5 * fact(4)
# ===> 5 * (4 * fact(3))
# ===> 5 * (4 * (3 * fact(2)))
# ===> 5 * (4 * (3 * (2 * fact(1))))
# ===> 5 * (4 * (3 * (2 * 1)))
# ===> 5 * (4 * (3 * 2))
# ===> 5 * (4 * 6)
# ===> 5 * 24
# ===> 120

 

    遞歸函數就像問路同樣,有去有回。A問B,B在問C,C知道答案返回給B,B在返回給A
    必須有一個明確的結束條件
    每次進入更深一層的遞歸時,問題規模相比上次遞歸應有所減小
    遞歸效率不高

 

  (3)尾遞歸優化

      尾遞歸是指,在函數返回的時候,調用自身自己,而且,return 語句不能包含表達式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def  fact(n):
         return  fact_iter(n,  1 )
 
def  fact_iter(num, product):
         if  num  = =  1 :
                 return  product
         # return 語句不能包含表達式。遞歸自己不管調用多少次,都只佔用一個棧幀
         return  fact_iter(num  -  1 , num  *  product)
 
# 運行過程:
# fact(5)
# ===> fact_iter(5, 1)
# ===> fact_iter(4, 5)
# ===> fact_iter(3, 20)
# ===> fact_iter(2, 60)
# ===> fact_iter(1, 120)
# ===>120
相關文章
相關標籤/搜索