天天看點

Cris 的Python日記(五):Python 資料結構之元祖,字典和集合

文章目錄

      • 0. 序
      • 1. range
      • 2. 元祖
      • 3. 可變對象
      • 4. 映射和字典
      • 5. 字典的常用方法
      • 6. 集合
      • 7. 腦圖

0. 序

蜉戀風,奈何生之短。風戀蜉,奈何死無期。陰陽從此兩相隔,極似人間愛恨情仇,故曰 謂風。

摘自·網易雲音樂《謂風》·熱評

1. range

# range()是一個專門用來生成自然數序列的函數
# 該函數需要三個參數:1.起始位置(可以省略,預設為0);2.終止位置(不能省略);3.步長(可以省略,預設為1)
# 和切片操作類似,也是留頭不留尾

r = range(5)
print(r)    # range(0, 5)
print(list(r))  # [0, 1, 2, 3, 4]

r = range(2, 10, 2)
print(list(r))  # [2, 4, 6, 8]
r = range(10, 2, -1)  # [10, 9, 8, 7, 6, 5, 4, 3]
print(list(r))

# 用處:主要是用作for 循環的指定範圍
for i in range(10):
    print(i)    # 0~9

for s in "string":
    print(s)
           

2. 元祖

# 元祖(tuple)和清單(list)基本一緻,其實就是不可變的清單
# 如果希望資料不可變,那麼使用元祖即可(實際開發使用較少)

# 建立元祖
names = ()
print(names, type(names))    # () <class 'tuple'>
names = ('james', 'cris', 'curry')
print(names)    # ('james', 'cris', 'curry')
print(names[2])  # curry

# 元祖是不可變序列,即不能為元祖中的元素重新指派;也不能新增或删除元素
# names[1] = 'simida' # 報錯

# 建立非空元祖可以省略括号,如下:
names = '詹姆斯', '科比'
print(names, type(names))    # ('詹姆斯', '科比') <class 'tuple'>
# 如果元祖隻有一個元素,如果不使用括号那麼該元素後面需要添加一個,來确定是元祖資料類型
# names = '雷奧',
names = ('cris')
print(names, type(names))   # cris <class 'str'>

# 元祖的解包(解構):就是将元祖中的每個值都指派給一個變量
names = 10, 11, 12, 13
a, b, c, d = names
print(a, b, c, d)  # 10 11 12 13

# 在對元祖進行解包,變量的數量需要和元祖中的元素的個數一緻
# 如果隻需要取前幾個元素的值,可以使用 * 來代替後面的所有元素成一個清單(但是不能同時寫多個*)
a, b, *c = names
print(a, b, c)    # 10 11 [12, 13]

a, *b, c = names
print(a, b, c)       # 10 [11, 12] 13

# 利用元祖的解包來進行變量值的交換
a = 100
b = 200
a, b = b, a
print(a, b)  # 200 100
           

3. 可變對象

# 可變對象:對象的值可以被改變
# 對象三要素:id/type/value
# 可變對象的典型例子就是清單;不可變對象的典型例子就是元祖
# 關于變量的指派和通過變量修改對象的值需要搞清楚這兩者的差別!

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True  == 比較值
print(a is b)   # False  is 和 is not 比較記憶體位址
print(a is not b)   # True
           

4. 映射和字典

# 字典屬于一種新的資料結構,叫做映射(mapping),和清單的作用類似,都是存儲對象的
# 清單存儲對象的性能很好,并且根據索引查詢的性能也很好,但是如果不知道具體的索引,那麼查詢的性能就很差了(需要挨個周遊才能查詢到指定的元素)
# 如果使用字典,就可以很塊的根據要求查詢到指定的元素(類似于java 的map)

# 字典基礎:字典中可以儲存多個對象,每個對象有一個唯一的key,而對象就是這個key 對應的value
# 是以字典也稱之為鍵值對,同時字典中的每個鍵值對都稱之為一個項(item)

# 文法:{key:value,key:value...}
d = {1: 'cris', 2: 'james', 3: 'curry'}
print(d, type(d))    # {1: 'cris', 2: 'james', 3: 'curry'} <class 'dict'>

# 字典的value 可以是任何值,但是key 必須是任意的不可變對象(int,str,bool,tuple...)
# 字典的鍵是不能重複的,如果出現重複的,否則後面會替換掉前面的。
# 推薦字典的鍵為 str 類型
# 字典的取值都是根據value 來擷取的
print(d[1])  # cris
           

5. 字典的常用方法

# 建立字典:使用{key:value,...}
# 或者使用 dict()函數

# 1. 使用dict(arg1=value,...)函數的方式,傳入的參數名就是key,值就是value,并且參數名預設資料類型就是str
d = dict(name='cris', age=12)
print(d, type(d))   # {'name': 'cris', 'age': 12} <class 'dict'>

# 2. 也可以将包含雙值子序列的序列轉換為字典
# 雙值序列:(1,2),['cris','james'],'ab'
# 子序列:序列中的元素仍然是序列,那個這個元素就可以稱之為子序列
d = dict([['name', 'james'], ('age', 23)])
print(d, type(d))    # {'name': 'james', 'age': 23} <class 'dict'>

# len()函數可以擷取字典中鍵值對的個數
print(len(d))   # 2

# in 和 not in:in 用于檢查字典是否包含指定的鍵,not in 用于檢查字典是否不包含指定的鍵
print('name' in d)  # True
print('sex' in d)   # False

# 擷取字典的值,根據鍵來擷取value
print(d['age'])  # 23
n = 'name'
print(d[n])  # james

# 通過[key] 擷取value,如果key不存在,那麼抛出 KeyError 異常
# 如果通過get()方法,如果key 不存在,不會報錯,直接傳回None
print(d.get('name'))    # james
print(d.get('hello'))   # None 不會報錯

# get(key,defaultValue)
print(d.get('sex', '男'))  # 可以傳入預設值,如果key 不存在,那麼傳回預設值

# 修改字典,如果key 存在就覆寫,不存在就添加
d['name'] = '詹姆斯'
print(d['name'])    # 詹姆斯

# setdefault(key,defaultValue),如果key 存在,那麼直接傳回對應的value
# 如果不存在,則向字典添加這個key,并傳回預設的value
print(d.setdefault('name', 'zhang3'))    # 詹姆斯
print(d.setdefault('sex', '人妖'))  # 人妖
print(d)  # {'name': '詹姆斯', 'age': 23, 'sex': '人妖'}

# update([other]):使用other 字典來更新原字典,如果有重複的key,則替換,沒有就添加
d.update({'name': 'simida', 'address': '洛杉矶'})
print(d)    # {'name': 'simida', 'age': 23, 'sex': '人妖', 'address': '洛杉矶'}

# del删除字典中的鍵值對,key 不存在抛出異常
del d['address']
print(d)    # {'name': 'simida', 'age': 23, 'sex': '人妖'}

# popitem():随機删除字典中的鍵值對,一般都是删除最後一個,傳回删除的鍵值對(元祖資料類型),如果字典是空的,抛出異常
print(d.popitem())  # ('sex', '人妖')

# pop(key):根據key 删除字典中的項,傳回被删除的項中的value,key 不存在就報錯
# 加上預設值,如果key 不存在就傳回預設值
print(d.pop('age'))  # 23
print(d.pop('abc', '這是預設值'))  # 這是預設值

# clear()清空字典
d.clear()
print(d)    # {}

# copy():淺複制,複制後的新對象和原對象獨立,但是隻會簡單的複制對象内部的值
# 如果對象内部的值也是可變資料類型,那麼這個值不會被複制,而是拷貝該值的位址
a = {'name': 'james', 'age': 12}
b = a.copy()
print(id(a) == id(b))   # False

a = {1: {'name': 'james', 'age': 22}}
b = a.copy()
b[1]['name'] = 'curry'
# {1: {'name': 'curry', 'age': 22}} {1: {'name': 'curry', 'age': 22}}
print(a, b)

# 字典的周遊:keys():傳回的是字典的所有key,以序列形式顯示
a = {'name': 'james', 'age': 12}
print(a.keys())  # dict_keys(['name', 'age'])
for key in a.keys():
    print(a[key])

# values():傳回的是字典的所有鍵值對的value,以序列形式顯示
print(a.values())   # dict_values(['james', 12])
for value in a.values():
    print(value)

# items():傳回字典所有的項,以序列形式顯示,每個元素都是一個雙值子序列
# 每個雙值子序列的元素就是每個項的鍵和值
for k, v in a.items():
    # k= name value= james
    # k= age value= 12
    print('k=', k, 'value=', v)
           

6. 集合

# 集合(set)和清單非常類似
# 1. 但是集合隻能存儲不可變資料類型(因為需要根據對象的hash值來存儲)
# 2. 集合中存儲的元素唯一且無序(和插入順序無關)

# 集合的建立:使用{}或者set()
s = {1, 23, 3, 23}
print(s)    # {1,3,23}
# 注意:使用{}表示建立的是一個空字典
s = set()
print(s, type(s))    # set() <class 'set'>

# 可以通過set()将序列和字典轉化為集合,可以用于去重
s = set([1, 2, 3, 2, 1, 5])
print(s)    # {1, 2, 3, 5}

# 将字典轉換為集合時,隻會包含字典中的鍵
s = set({1: 'cris', 2: 'james', 3: 'curry'})
print(s)    # {1, 2, 3}

# 集合沒有辦法通過索引去操作元素,類似java 的set,但是可以通過list()轉換

# 可以使用 in 和 not in 來檢查元素
# 可以使用len()計算集合中元素個數
# 使用add()向集合中添加元素,沒有傳回值
s.add(29)

# update():可以傳遞序列,集合,字典(隻會擷取字典所有的key)
s.update({3, 1, 'hello'})
print(s)    # {1, 2, 3, 'hello', 29}
s.update([1, 2, 4])
print(s)    # {1, 2, 3, 4, 'hello', 29}
s.update({1: 'cris', 11: 'james'})
print(s)    # {1, 2, 3, 4, 11, 'hello', 29}

# pop:随機删除集合中的元素,有傳回值
s.pop()
s.pop()
print(s)    # {3, 'hello', 29}

# remove:删除集合中的指定元素,沒有傳回值
s.remove(29)
print(s)

# clear()清空
# copy()淺複制

# 集合的運算
s1 = {1, 2, 3, 4}
s2 = {2, 3, 5, 6}
# & 交集運算
print(s1 & s2)  # {2,3}
# | 并集運算
print(s1 | s2)  # {1,2,3,4,5,6}
# - 差集運算
print(s1 - s2)  # {1,4}
print(s2 - s1)  # {5,6}
# ^ 異或集:擷取兩個集合不相交的部分
print(s1 ^ s2)  # {1,4,5,6}
# <= 檢查一個集合是否是另一個集合的子集:子集就是該集合的每個元素都在另一個集合中出現
print({1, 2} <= {1, 2})  # True
# < 檢查一個集合是否是另一個集合的真子集:超集不僅含有子集所有的元素,還含有子集沒有的元素
print({1, 2} < {1, 2})    # False
# >= 和 > 同上
           

7. 腦圖

Cris 的Python日記(五):Python 資料結構之元祖,字典和集合