1. 程式人生 > >Python基礎之元祖,集合及深淺copy

Python基礎之元祖,集合及深淺copy

把這三塊知識點放在一起寫,是因為這三點內容都很少。
寫部落格可真是件費時費力的活 ,٩(º﹃º٩)

文章目錄

元祖(tuple)

元祖和列表很相似,也是任意型別的值的一個序列,並且按照整數下標索引。但是需要注意的是:元祖是不可變資料型別
語法上,元祖就是一行用逗號分隔開的值

t = 'python', 6324, '人生苦短', ['skr', False]
print(t)  # ('python', 6324, '人生苦短', ['skr', False])

但是在寫法上約定俗成,需要用括號括起來

t = ('python', 6324, '人生苦短', ['skr', False])

如果元祖中只包含一個元素,那麼需要在後面新增一個逗號

t =
('python',) print(t, type(t)) # ('python',) <class 'tuple'> t1 = ('python') # 這裡的t1並沒有轉化為tuple,還是字串本身 print(t1, type(t1)) # python <class 'str'>

也可以用內建函式 tuple() 新建一個空的元祖

t = tuple()
print(t)  # ()

在 tuple() 中可以加入引數,將引數的型別轉化為元祖,並返回一個元祖。

t1 = tuple('python')
print(t1)  # ('p', 'y', 't', 'h', 'o', 'n')
t2 = tuple([6324, 'python', [1, 2, '帶帶大師兄']])
print(t2)  # (6324, 'python', [1, 2, '帶帶大師兄'])
t3 = tuple(t2)
print(t3)  # (6324, 'python', [1, 2, '帶帶大師兄'])

因為元祖是不可變資料型別,所以在元祖中並沒有太多的操作。

len(tuple)

計算元組內元素個數

t = (6324, 'python', [1, 2, '帶帶大師兄'])
print(len(t))  # 3

del tuple

刪除元祖

t = (6324, 'python', [1, 2, '帶帶大師兄'])
del t
print(t)  # 會報錯:name 't' is not defined

集合(set)

集合也是一系列值的序列,它是可變資料型別,但集合中的元素必須是不可變資料型別。集合中的元素不重複且無序。
set 的建立及型別轉化

set1 = {1, 'python', (6324, '人生苦短')}
print(set1, type(set1))  # {1, (6324, '人生苦短'), 'python'} <class 'set'>
set2 = {}
print(set2, type(set2))  # {} <class 'dict'>
set3 = set(set2)
print(set3, type(set3))  # set() <class 'set'>

set.add(elmnt)

給集合中新增元素,若元素已經存在,則不執行任何操作。

set1 = {1, 'python', (6324, '人生苦短')}
set1.add('life')
print(set1)  # {1, (6324, '人生苦短'), 'life', 'python'}

set.update(set1)

將set1中的元素更新到set中去,set1 可以是集合和元素。如果新增的元素在集合中已存在,則該元素只會出現一次,重複的會忽略。

set1 = {1, 'python', (6324, '人生苦短')}
set1.update('life')
print(set1)  # {'l', 1, (6324, '人生苦短'), 'python', 'f', 'e', 'i'}
set2 = {1, 'python', (6324, '人生苦短')}
set2.update({'life', 1, (1, 3)})
print(set2)  # {1, (6324, '人生苦短'), (1, 3), 'life', 'python'}

set.pop()

隨機移除集合中的一個元素

set1 = {1, 'python', (6324, '人生苦短')}
set1.pop()
print(set1)

set.remove(item)

在集合中刪除指定元素,但指定元素不存在時會發生錯誤。

set1 = {1, 'python', (6324, '人生苦短')}
set1.remove('python')
print(set1)  # {1, (6324, '人生苦短')}
set1.remove('life')  # 此處會報錯

set.discard(value)

在集合中刪除一個指定的值,這個值可以不存在於集合中

set1 = {1, 'python', (6324, '人生苦短')}
set1.discard('python')
print(set1)  # {1, (6324, '人生苦短')}
set1.discard('life')
print(set1)  # {1, (6324, '人生苦短')}

set.clear()

清空集合中的所有元素

set1 = {1, 'python', (6324, '人生苦短')}
set1.clear()
print(set1)  # set()

del

刪除集合

set1 = {1, 'python', (6324, '人生苦短')}
del set1

因為集合內部元素是不可變資料型別,所以集合沒有改操作。


x in set若 x 在 set 中,返回 True

set1 = {1, 'python', (6324, '人生苦短')}
flag = 'python' in set1
print(flag)  # True

其他操作

交集(& 或者 intersection)

set1 = {1, 3, 5, 2, 8}
set2 = {2, 4, 1, 7, 9}
print(set1 & set2)  # {1, 2}
print(set1.intersection(set2))  # {1, 2}

並集(| 或者 union)

set1 = {1, 3, 5, 2, 8}
set2 = {2, 4, 1, 7, 9}
print(set1 | set2)  # {1, 2, 3, 4, 5, 7, 8, 9}
print(set1.union(set2))  # {1, 2, 3, 4, 5, 7, 8, 9}

差積(- 或者 difference)

set1 = {1, 3, 5, 2, 8}
set2 = {2, 4, 1, 7, 9}
print(set1 - set2)  # {8, 3, 5}
print(set1.difference(set2))  # {8, 3, 5}

反交集(^ 或者 symmetric_difference)

set1 = {1, 3, 5, 2, 8}
set2 = {2, 4, 1, 7, 9}
print(set1 ^ set2)  # {3, 4, 5, 7, 8, 9}
print(set1.symmetric_difference(set2))  # {3, 4, 5, 7, 8, 9}

子集(< 或者 issubset)

set1 = {1, 3, 5}
set2 = {1, 3, 5, 2, 8}
print(set1 < set2)  # True
print(set1.issubset(set2))  # True

超集(> 或者 issuperset)

set1 = {1, 3, 5, 2, 8}
set2 = {1, 3, 5}
print(set1 > set2)  # True
print(set1.issuperset(set2))  # True

frozenset()

返回一個凍結的集合,凍結後集合不能再新增或刪除任何元素。

set1 = frozenset('python')
print(set1, type(set1))
# frozenset({'p', 'n', 'o', 'y', 'h', 't'}) <class 'frozenset'>

深淺copy

在賦值運算中,將 A 的值賦值給 B ,實際上 A 與 B 是指向同一個記憶體空間的。

l1 = [4396, 6324, ['python', 'life']]
l2 = l1

l1[0] = 2700
print(l1)  # [2700, 6324, ['python', 'life']]
print(l2)  # [2700, 6324, ['python', 'life']]
l1[2][1] = 'user'
print(l1)  # [2700, 6324, ['python', 'user']]
print(l2)  # [2700, 6324, ['python', 'user']]

print(id(l1))  # 2828857390600
print(id(l2))  # 2828857390600

淺copy

l1 = [4396, 6324, ['python', 'life']]
l2 = l1.copy()

print(id(l1))  # 1958647117320
print(id(l2))  # 1958647969864
print(id(l1[0]))  # 1958646961232
print(id(l2[0]))  # 1958646961232
print(id(l1[2][0]))  # 1958647087824
print(id(l2[2][0]))  # 1958647087824

在 淺copy 中只是在記憶體中開闢了一塊新空間儲存新列表。但是新列表和原列表中的元素還是公用的,儲存在統一地址內。

深copy

import copy

l1 = [4396, 6324, ['python', 'life']]
l2 = copy.deepcopy(l1)

print(id(l1))  # 1826240527624
print(id(l2))  # 1826240631368
print(id(l1[0]))  # 1826208928848
print(id(l2[0]))  # 1826208928848
print(id(l1[2][0]))  # 1826209055440
print(id(l2[2][0]))  # 1826209055440
print(id(l1[-1]))  # 1826240527432
print(id(l2[-1]))  # 1826240631304

在深copy中,新列表的記憶體空間是新建的,列表中的可變資料型別的空間也是新建的,但是不可變資料型別依然是公用的。

補充:小資料池,程式碼塊

Python 在記憶體機制上有兩個需要了解的地方:小資料池,程式碼塊。
點選閱讀相關博文