本文將會總結以下幾個知識點:
- 列表推導式
-
==
和is
- 深拷貝和淺拷貝
列表推導式
需求:如果我們想生成一個連續(xù)的列表,可以采用哪些方式呢蒸甜?首先可以使用 for
和 while
循環(huán):
def createList(num):
lis = []
for i in range(num):
lis.append(i)
return lis
print(createList(10))
def createList(num):
lis = []
count = 0
while True:
if num == count:
break;
else:
count += 1
lis.append(count)
return lis
print(createList(10))
如果我們想在生成列表的時候進行篩選棠耕,可以這樣做:
def createList(num):
lis = []
for i in range(num):
if not i%2:
lis.append(i)
return lis
print(createList(10))
def createList(num):
lis = []
count = 0
while True:
if num == count:
break;
else:
count += 1
if not count % 2:
lis.append(count)
return lis
print(createList(10))
上面的代碼可以生成任何我們想要的列表余佛,但是代碼量有點多,因此窍荧,Python 提供了列表推導式讓我們快捷生成列表辉巡,其格式為:
[ 變量 for 表達式 判斷條件 ]
上面的變量有且只能有一個,如果需要多個變量蕊退,可以采用列表或元組的方式實現(xiàn)郊楣。下面是一些常見用途:
1.生成一個列表:
def createList(num):
return [i for i in range(num)]
print(createList(10))
運行結果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2.生成列表時進行篩選:
def createList(num):
return [i for i in range(num) if not i%2]
print(createList(10))
運行結果:
[0, 2, 4, 6, 8]
3.循環(huán)嵌套,生成多維列表
def createList(num):
return [(i,j) for i in range(num) for j in range(3)]
print(createList(3))
運行結果:
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
上面就是列表推導式的簡單用法瓤荔。
==
和 is
Python 中痢甘,==
用來判斷兩個變量的值是否相同,is
用來判斷兩個變量是否指向同一塊內存空間茉贡。
看如下實例:
a = [1,2,3]
b = a
c = [1,2,3]
d = [1,2,3,4]
print("a == b: %s"%(a == b))
print("a == c: %s"%(a == c))
print("b == c: %s"%(b == c))
print("a == d: %s"%(a == d))
運行結果:
a == b: True
a == c: True
b == c: True
a == d: False
如上塞栅,a
,b
腔丧,c
三個變量的值相同放椰,都是 [1,2,3]
,因此使用 ==
操作符判斷的結果為 True
愉粤,a
砾医,b
,c
與 d
的值不相同衣厘,因此判斷的結果為 False
如蚜。
再來看下 is
運算符:
a = [1,2,3]
b = a
c = [1,2,3]
d = [1,2,3,4]
print("a == b: %s"%(a is b))
print("a == c: %s"%(a is c))
print("b == c: %s"%(b is c))
print("a == d: %s"%(a is d))
運行結果:
a == b: True
a == c: False
b == c: False
a == d: False
上例中,只有 a
和 b
變量指向同一塊內存影暴,因此對它們使用 is
操作符判斷的結果為 True
错邦,而其他的幾個判斷返回 True
。
深拷貝和淺拷貝
實現(xiàn)深拷貝和淺拷貝型宙,可以使用函數(shù)遞歸完成撬呢,也可以使用 Python 內置的 copy
模塊。深拷貝使用 deepcopy
函數(shù)妆兑,淺拷貝使用 copy
函數(shù)魂拦。
深拷貝和淺拷貝的區(qū)別如下:
- 深拷貝會對變量進行遞歸拷貝,拷貝后的值和原始值之間沒有引用關系
- 淺拷貝只對變量的外層進行拷貝搁嗓,拷貝后內層值與原始值之間扔存在引用關系
看一下深拷貝的例子:
from copy import deepcopy
a = [1,2,3]
b = [4,5,6]
# c 中保存了 a 和 b 的引用芯勘,修改 a 和 b 的值會同步影響到 c 的值
c = [a,b]
# 對 c 進行深拷貝
d = deepcopy(c)
# 修改 a 的值
a.append(666)
# 打印 c 和 d
print(c)
print(d)
print(c is d)
運行結果如下:
[[1, 2, 3, 666], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6]]
False
進行深拷貝時,會對變量內部一層一層進行遞歸拷貝腺逛,拷貝到新變量中的值和原始值之間沒有引用關系荷愕,修改原始值不會影響到新變量中的值。示意圖如下:
接下看看一下淺拷貝的例子:
from copy import copy
a = [1,2,3]
b = [4,5,6]
# c 中保存了 a 和 b 的引用,修改 a 和 b 的值會同步影響到 c 的值
c = [a,b]
# 對 c 進行淺拷貝
d = copy(c)
# 修改 a 的值
a.append(666)
# 打印 c 和 d
print(c)
print(d)
print(c is d)
運行結果如下:
[[1, 2, 3, 666], [4, 5, 6]]
[[1, 2, 3, 666], [4, 5, 6]]
False
可見路翻,淺拷貝只能對外層進行拷貝狈癞,而對于內層的值不會進行拷貝,仍然指向原始的引用茂契。示意圖如下:
對元組進行淺拷貝
修改代碼蝶桶,實現(xiàn)對元組進行淺拷貝:
from copy import copy
a = [1,2,3]
b = [4,5,6]
c = (a,b)
d = copy(c)
print(c is d)
print(id(c),id(d))
運行結果如下:
True
17322512 17322512
修改代碼,實現(xiàn)對元組進行深拷貝:
from copy import deepcopy
a = [1,2,3]
b = [4,5,6]
c = (a,b)
d = deepcopy(c)
print(c is d)
print(id(c),id(d))
運行結果如下:
False
15881080 15207040
可見掉冶,進行淺拷貝時真竖,如果是不可變類型,則不會對外層進行拷貝厌小,調用 copy
函數(shù)的返回值仍然是指向原始值的一個引用恢共,進行深拷貝時才會對外層和內層進行拷貝,這點需要注意璧亚。
完讨韭。