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'
}
|
(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
|
s
=
frozenset
(
'hello'
)
print
(s)
# 執行結果:
# frozenset({'h', 'e', 'o', 'l'})
|
使用 frozenset 定義的集合,沒有 add 或者 pop 等方法
(1)函數表現形式
python中函數的定義方法:
1
2
3
4
|
def
test(x):
"The function definitions"
x
+
=
1
return
x
|
def: 定義函數關鍵字
test: 函數名(): 內可定義參數"": 文檔描述(非必要,強烈建議添加函數信息描述)
x+=1 : 泛指代碼塊或程序處理邏輯
return: 定義返回值
調用運行:能夠帶參數也能夠不帶函數名()
使用函數的好處:
代碼重用
保持一致性,易維護
可擴展
函數返回值:
返回值 = 0 : 返回 None
返回值 = 1 : 返回 object
返回值數 > 1: 返回 tuple
(2)函數的參數
建議參考:廖老師python3函數的參數
若是函數的內容無 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
|
(1)函數即變量
1
2
3
4
5
6
7
8
|
def
test():
pass
t
=
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
n
=
=
1
:
return
1
return
n
*
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
|