P03-List and Dictionary#
當然,以下是中文版本的資料結構說明:
Objectives
List(串列)
串列的創建與定義:使用方括號
[]
來定義一個串列。例如:
my_list = [1, 2, 3]
串列的屬性:
有序(Ordered)
可索引(Indexable)
可變(Mutable)
串列操作:
增加元素:
append()
,extend()
,insert()
刪除元素:
remove()
,pop()
,del
通過索引訪問:
my_list[0]
(返回第一個元素)
串列切片(Slicing):
例如:
my_list[1:3]
(返回索引為1和2的元素)
巢狀串列(Nested List):
例如:
nested_list = [[1, 2], [3, 4]]
Dictionary(字典)
字典的創建與定義:使用大括號
{}
來定義一個字典。例如:
my_dict = {'key1': 'value1', 'key2': 'value2'}
字典的屬性:
無序(Unordered)
以鍵值對(Key-Value Pairs)的形式儲存
可變(Mutable)
巢狀字典(Nested Dict):
例如:
nested_dict = {'outer_key': {'inner_key': 'value'}}
字典函數:
.keys()
:返回所有鍵.values()
:返回所有值.items()
:返回所有鍵值對.get()
:取得指定鍵的值.update()
:更新字典
字典的替代方案:
defaultdict()
:自動創建不存在的鍵並賦予預設值Counter()
:計數物件的頻率
Practice: YouBike data
read data from url
convert data to json format
extract data from json format
convert data to list and dict
Link to useful data
List#
在Python程式語言中,List(串列) 是一種有序集合(ordered collection)。List能夠容納多種不同型態的元素,包括數值、字串、其他資料結構,甚至是函式。每個元素都會被指定一個從0開始的索引(index)。
定義與建立
一個List可以通過方括號([]
)來定義,並可用等號(=
)賦值給一個變數。方括號內的元素由逗號(,
)分隔。
empty_list = [] # 空的List
number_list = [1, 2, 3] # 數值型List
mixed_list = [1, "two", 3.0] # 混合型態的List
List的特性
有序性(Ordered): List的元素有明確的順序。
可索引存取(Indexed): 可以用索引來存取List中的元素,從頭(正數索引)或尾(負數索引)。
可變性(Mutable): List的內容可以被修改,包括增加、刪除和更新元素,因而不能當成Dict(字典)的鍵(key)。
常用操作
新增元素
.append(element)
: 在List尾部增加單一元素。.extend([elements])
: 在List尾部增加多個元素。
刪除元素
.pop()
: 移除並返回List尾部的元素。
索引存取
list[index]
: 存取特定索引位置的元素。
my_list = [1, 2, 3]
print(my_list)
my_list.append(4) # [1, 2, 3, 4]
print(my_list)
my_list.extend([5, 6]) # [1, 2, 3, 4, 5, 6]
print(my_list)
my_list.pop() # 返回 6,my_list 變成 [1, 2, 3, 4, 5]
print(my_list)
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5]
資料型態的一致性
雖然List可以包含不同型態的元素,但在實際應用中,為了程式碼寫簡單和效能考量,通常會讓List內的所有元素型態保持一致。
Access a List#
在Python中,List的索引(Index)是從0開始的。以alist = [3, 4, 5]
為例,元素3
位於索引0
的位置,因此可以用alist[0]
來存取它。同理,元素4
位於索引1
的位置,可用alist[1]
來存取。以下為基本規則:
從頭開始索引:
Python List的索引從0開始計數。最後元素的索引:
若List的長度為n
,則最後一個元素的索引將會是n - 1
。負數索引:
alist[-1]
可用來存取List的最後一個元素,alist[-2]
則為倒數第二個元素,依此類推。
用途舉例:更新List內容
要修改List中特定索引的元素,您可以使用賦值運算符(=
)來重新賦值。例如,alist[2] = 6
會將索引2
的元素更改為6
。
alist = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
# print whole list
print(alist)
# print the last one element
print(alist[-1])
# print the first and second elements
print(alist[0], alist[1])
# print the length of the list by function len()
print(len(alist))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
1
10 9
10
Slice a List#
基本操作
在Python的List中,切片(Slicing)是一個非常實用的特性,讓我們能夠取出List中一段連續(或不連續)的元素。基本語法是alist[start:stop:step]
,其中start
是起始索引,stop
是結束索引(不包括此索引),step
是步進值。以下為基本用法:
從索引 1 到 2:
alist[1:3]
會取得索引從1到2(不包含3)的元素,因此會取得alist
中索引為1和2的元素。倒數第三個到倒數第一個:
alist[-3:-1]
會取得從倒數第三個到倒數第二個的元素(注意這裡不包含倒數第一個)。前三個元素:
alist[:3]
會取得alist
中前三個元素,即索引0、1、2。除了最後三個以外的所有元素:
alist[:-3]
會取得直到倒數第四個元素的所有元素。從第三個元素到最後:
alist[3:]
會取得從索引3開始到最後的所有元素。從倒數第三個元素到最後:
alist[-3:]
會取得從倒數第三個元素到最後的所有元素。
進階用法
每隔一個(step=2)的切片:
alist[::2]
會取得索引為0、2、4…的元素。反轉List:
alist[::-1]
會得到一個完全反轉的新List。
# print the 1 to 2 elements
alist = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
print(alist[0:2])
print(alist[:2])
# print the last 3 to 2 elements from the end
print(alist[-3:-1])
print(alist[:3])
print(alist[:-3])
print(alist[3:])
print(alist[-3:])
[10, 9]
[10, 9]
[3, 2]
[10, 9, 8]
[10, 9, 8, 7, 6, 5, 4]
[7, 6, 5, 4, 3, 2, 1]
[3, 2, 1]
Update List:append()
, extend()
and +
operator#
在Python中,更新List的元素可以透過多種方式,其中append()
、extend()
和+
操作符是常用的方法。雖然這三種操作在名稱或用法上可能相似,但它們有著不同的用途和效果。
append()
方法#
append()
用於在List的末尾追加一個元素。如果您追加的是另一個List,那麼這個List會作為單一元素添加到原List的末尾。
alist = [1, 2, 3]
blist = [3, 2, 1]
alist.append(2) # 結果會是 [1, 2, 3, 2]
print(alist) #
alist.append(blist)
print(alist) # 結果會是 [1, 2, 3, 2, [3, 2, 1]]
[1, 2, 3, 2]
[1, 2, 3, 2, [3, 2, 1]]
extend()
方法#
append()
是把某一物件當成最後一個元素加入List的最末,但extend()
則是用於合併兩個List,把第二個List的所有元素追加到第一個List的末尾。
alist = [1, 2, 3]
blist = [3, 2, 1]
alist.extend(blist) # 結果會是 [1, 2, 3, 3, 2, 1]
print(alist)
alist.append(blist)
print(alist)
[1, 2, 3, 3, 2, 1]
[1, 2, 3, 3, 2, 1, [3, 2, 1]]
+
操作符#
使用+
操作符也能達到合併List的效果,但其不像append()
或extend()
操作後就會更改內容,其不會更改原有的alist
,必須要透過重新賦值給alist
才能達到相同的效果。
結論
alist.extend(blist)
會修改原來的alist
,使其包括blist
的所有元素。alist = alist + blist
或alist += blist
會有相同的效果,也就是合併兩個List,但這需要重新賦值給alist
。
alist = [1, 2, 3]
blist = [3, 2, 1]
print(alist + blist)
print(alist)
alist.extend(blist)
print(alist)
[1, 2, 3, 3, 2, 1]
[1, 2, 3]
[1, 2, 3, 3, 2, 1]
Access Nested List#
在Python中,List不僅可以存儲基本數據類型(如整數、浮點數和字符串)的元素,還可以存儲其他的資料結構,包括另一個List。當一個List內部包含另一個List時,我們稱之為「雙層List」或「嵌套(Nested)List」。
存取嵌套元素: 存取雙層List的元素稍微複雜一點,因為每個元素本身也可能是一個List。例如,我們有一個雙層List nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
。
存取第一個子List可以用
nested_list[0]
,這會返回[1, 2, 3]
。如果要存取子List中的具體一個元素,比如第一個子List中的第二個元素(也就是2),則可以使用
nested_list[0][1]
。
多維索引: 在雙層或多層嵌套List中,你可以透過多維索引來存取元素。例如,nested_list[0][1]
中的第一個索引 0
是外層List的索引,第二個索引 1
是內層List的索引。
更新嵌套List: 更新雙層List的元素與單層List相似,只是你需要指定更多的索引層級。例如,如果你想將上面例子中的數字2改為20,可以這樣做:nested_list[0][1] = 20
。
遍歷雙層List: 雙層List也可以使用嵌套的迴圈來遍歷。例如,
for sublist in nested_list:
for element in sublist:
print(element)
mlist = [[1, 2, 3, 4, 5, 6, 7],
[11, 12, 13, 14, 15, 16, 17],
[21, 22, 23, 24, 25, 26, 27]]
print(mlist[2][5])
26
alist = [1, 2, 3, 4, 'abc', '123', '123.1', [1, 2, 3] ]
print(len(alist)) #length len()
print(alist[7], type(alist[7]))
# Access any elements in the second layers of alsit
print(alist[-1][2]) # Review: -1 indicates the last element in a list
8
[1, 2, 3] <class 'list'>
3
Dictionary(字典)#
在Python中,Dictionary(通常簡稱為dict)是一種極為靈活並廣泛使用的數據結構。dict是用於存儲鍵(key)與值(value)對應的集合。與List不同,dict的元素並不是按照順序來排列的,因此我們不能用索引(index)來存取元素,而是要用相應的鍵。
基本語法:
例如,考慮以下的dict,在這個例子中,你可以通過鍵來存取相對應的值。adict[1]
會返回3
,而adict['2']
會返回4
。adict = {1: 3, '2': 4}
鍵的不可變性(Immutable):
Dict的鍵可以是多種不同的數據類型,例如整數、浮點數、字符串等。然而,有一些數據類型(如List和另一個dict)是不允許作為鍵的。這是因為這些數據類型是「可變」的,意即你可以在任何時間點修改它們的內容,這可能會導致數據不一致或錯誤。值的多樣性:
Dict的值(value)可以是任何數據類型,包括基本類型(如整數、字符串)和其他的數據結構(如List、Tuple、另一個dict等)。Nested Dictionary:
Dict中的值也可以是另一個dict,這種結構稱為「Nested (嵌套)Dictionary」。例如,在這個例子中,nested_dict['key1']
會返回一個dict:{'subkey1': 1, 'subkey2': 2}
。nested_dict = {'key1': {'subkey1': 1, 'subkey2': 2}, 'key2': {'subkey3': 3}}
其他注意事項
Tuple可以作為dict的鍵,因為它是不可變的(Immutable);List不可以作為dict的鍵,因為它是可變的(Mutable)。
使用
.get()
方法來存取鍵可以避免引發KeyError。例如,adict.get('key', 'default_value')
。但我們通常會使用adict['key']
來存取鍵,因為這樣可以讓程式碼更簡潔。使用
.keys()
和.values()
方法,你可以分別獲取dict中所有的鍵和值。update()
方法可以用來合併兩個dict。例如,adict.update(bdict)
會將bdict
中的所有鍵值對合併到adict
中。
adict = {1:3, '2':4}
print(adict[1], adict['2'])
alist = [1, 2, 3, "a", 'b', 'c', [1, 2, 3], [4, 5, 6]]
print(len(alist))
adict = {'3':3, 2:4, '3':5, '4':6, 1.13: '123', 'a': alist}
print(len(adict))
print(type(adict))
print(adict['a'][6][1])
bdict = {1:alist, 2:adict}
print(bdict[2]['a'][6][1])
3 4
8
5
<class 'dict'>
2
2
Accessing dictionary#
在Python中,存取Dictionary(或簡稱為dict)的元素主要是通過其對應的鍵(key)來實現。以下是一些常見的操作方式:
印出整個字典:使用
print()
函數可以輸出整個字典的內容。例如以下例子會會列印出bdict
字典中所有的鍵值對。print(bdict)
使用鍵來存取值:如果你知道某個鍵(key),就可以直接用這個鍵來獲取其對應的值(value)。下例這將會打印出與鍵
'3'
相關聯的值。print(adict['3'])
獲取所有鍵和值:你可以使用
.keys()
和.values()
方法來分別獲取所有的鍵和值。下例.keys()
將返回一個包含所有鍵的列表,而.values()
將返回一個包含所有值的列表。print(adict.keys()) print(adict.values())
# access the dictionary
# print whole dict
print(bdict)
# print the value of key '1'
print(adict['3'])
# print the value of key 1
print(adict.keys())
print(adict.values())
# print the first element of the list mapped by key 4
{1: [1, 2, 3, 'a', 'b', 'c', [1, 2, 3], [4, 5, 6]], 2: {'3': 5, 2: 4, '4': 6, 1.13: '123', 'a': [1, 2, 3, 'a', 'b', 'c', [1, 2, 3], [4, 5, 6]]}}
5
dict_keys(['3', 2, '4', 1.13, 'a'])
dict_values([5, 4, 6, '123', [1, 2, 3, 'a', 'b', 'c', [1, 2, 3], [4, 5, 6]]])
Counter() and defaultdict()#
有兩個資料結構與dict非常近似,一個是 defaultdict()
,另一個是 Counter()
。
defaultdict()
#
defaultdict()
是一個非常方便的資料結構,來自於 collections
模塊。它的主要優點是當你試圖存取一個不存在的鍵時,它會自動初始化這個鍵,而不會引發 KeyError
。在創建 defaultdict
的時候,你可以傳入一個工廠函數,用於生成預設值。例如:
from collections import defaultdict
adict = defaultdict(list)
adict['a'].append(1)
adict['b'].append(2)
adict['a'].append(3)
print(adict)
bdict = defaultdict(int)
bdict['a'] += 1
bdict['b'] += 1
print(bdict)
defaultdict(<class 'list'>, {'a': [1, 3], 'b': [2]})
defaultdict(<class 'int'>, {'a': 1, 'b': 1})
defaultdict()
與 dict
的比較::使用普通的 dict
,你需要手動檢查鍵是否存在或使用 setdefault
方法:
d = {}
d.setdefault('a', []).append(1)
Counter()
#
Counter
是另一個來自於collections
模塊的資料結構,專門用於計數。它非常適合於頻率計數等應用。Counter
可以使用most_common(n)
方法來獲取出現次數最多的n
個元素。Counter
與dict
的比較::
使用普通的dict
進行計數會相對複雜,需要檢查每個鍵是否已經存在於字典中:
from collections import Counter
c = Counter(['a', 'b', 'c', 'a', 'b', 'a'])
print(c)
print(c.most_common(2))
Counter({'a': 3, 'b': 2, 'c': 1})
[('a', 3), ('b', 2)]