3. List and dictionary

List的學習項目包含List的定義、存(附加新的元素、更新內容)、取(讀取)

L01. List Introduction

List(你可以中譯為串列,上課中會說List)。顧名思義,「a list of something」,通常代表的是「something arranged in order」。也就是把一群物件、東西、數值、變數照順序排好。List就是這樣的結構。只要放進List中,他就會被給予一個整數編號,而整數編號從0開始編起。在下列程式=(assignment)右側為List([]是一個空的List),當其被assign給左側時,左側的變項就是List型態。

alist = [] alist = [3, 4, 5]

List中的內容不一定要同型態,List中也可以有List,也可以同時有float(浮點數)、int(整數)或str(字串)等多種變數型態的數值。但多半在實際寫程式時,會盡量讓list中內容的變數型態維持一致。

L02. Access List

L02.1 by index

alist = [3, 4, 5]而言,3就放置在alist的0的位置,可用alist[0]存取;4就放置在alist的1的位置,可用alist[1]存取。當要存取一個list中某一個內容時,就把數值或其他變數Assign給相對應的位置。例如alist[3] = 4

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[1])
print(alist[2])

# print the length of the list by function len()
print(len(alist)) # length of 

L02.2 Slicing

有時候我們不只要取出一個元素,而是要取出list中第n個到第m個元素,這樣的動作可稱為Slicing。下面程式碼可取出list中最後一個元素,或者取其中數個元素。以alist[1:3]為例,其取index從1開始到3之前。所以是1與2。而alist[-3:-1]則是取-3開始到-1之前

# print the 1 to 2 elements
print(alist[1:3])

# print the last 3 to 2 elements from the end
print(alist[-3:-1])

L03. Update list content

用assignment就可以更動List的值,如alist[3] = 4。但我們更經常隨著for-loop要在List後面新增元素。或者把兩個List給合併起來,前者稱為append(),後者稱為extend()

# Append two integers to alist one by one
alist.append(3)
alist.append(4)

# Extend alist with another list [3, 4, 5]
alist.extend([3, 4, 5])

# Append alist with another list [3, 4, 5]
alist.append([3, 4, 5])

# print out alist to see what happens
print(alist)

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 3, 4, 3, 4, 5, [3, 4, 5]]

Using + to concatinate two lists

print([1, 2, 3] + [4, 5, 6])

[1, 2, 3, 4, 5, 6]

L04. Hierarchical List

L04.1 Access two-layer list

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[7][1], type(alist[7][1])) # index

D01. Dictionary introduction

Dictionary(你可以中譯為「字典」,但上課會直接稱之為dict)如同其字面上的意思,是給人就單字查詢意義的。在python中也不例外,他所存放的是「key to value pairs」。所以實際上他的內容並沒有順序,所以他不像list是用index 0, 1, 2...來存取。他是用key來存取value。在下面的例子中adict[1]所對應的值就是32所對應的值就是4

adict = {1:3, '2':4}

雖然說是key和value,但其中的value也可以是list,或者是另一個dictionary。而一個list中,也可以擺放很多個dictionary,簡單地說,就是list中可以有dictionary或list,dictionary可對應到list或dictionary。唯獨要注意的是,list或dictionary,不可以當作dictionary的key,這是為了怕寫程式的人亂改list或dictionary作為key的值,導致對應錯誤。但tuple可以作為dictionary的key。

D01. Initialize dict

adict = {}
bdict = dict()
print(adict, bdict)

{} {}

D02. Access dictionary

alist = [1, 2, 3, 4, 5, 6, 7, [10, 20, 30, 40]]
adict = {1:3, 2:4, 3:5, 4:6, '1':3, 1.13:'123', 'a': alist}
print(type(adict['a'][7][3]), len(adict['a'][7]))
print(adict['1'])
print(adict[1.13])

Output

<class 'int'> 4
3
123

D03. Update a dictionary

就是用跟list很接近的語法把他加進去而已。list會用這種方式來覆蓋或取出list裡面的值,例如alist[3] = 5。而dict也可以這麼做adict[3] = 5。你可以想像說list是指定index為3的項目要被取代,dict則是指定key為3的項目要被取代。但要記得,如果list要新增一個值,要用append()的方式如alist.append(3),且index會自動加上去,而dict要新增一個key-to-value pair,則直接寫adict[key] = value即可。

在底下的程式碼中,我新增一個adict後即刻新增一個key為3的key-to-value pair,然後我用一個for-loop新增了10個key-to-value的pair。注意key若被重複assign,就會被更新,如下

adict = {}
adict[3] = "hahaha"
for i in range(10):
    adict[i] = i*10
print(adict)

Case study: Accessing youbike data

資料說明youbike data link)。資料來自台北市政府的Youbike即時更新資料,https://tcgbusfs.blob.core.windows.net/blobyoubike/YouBikeTP.gz 下載後不用解壓縮。規格如右連結http://goo.gl/pmcIo3 此外,「最後更新時間」欄位之內容為詮釋資料更新時間,非資料檔案更新時間,實際資料檔案更新時間為「每1分鐘」,可參考檔案內容之「mday」欄位。

獲取youbike資料

  1. requests套件的.get()獲取該url的回應。

  2. 將該http request response的文字抽取出來response.text,資料型態為str

  3. 將抽取出來的文字,我知道他是用json格式存,因此用json.loads()將其轉換為python的資料型態,也就是由層層list與dictionary所套疊起來的資料

  4. 最後一一存取其內容

# import requests library to send web query
import requests

# import json library to parse json format
import json

response = requests.get('https://tcgbusfs.blob.core.windows.net/blobyoubike/YouBikeTP.gz')
print(type(response)) # <class 'requests.models.Response'>
print(type(response.text)) # <class 'str'>
data = json.loads(response.text)

測試出一筆資料的結構

  1. 如果偵測出他是一個list,那就取出第0筆資料往下追蹤。

  2. 如果偵測出他是一個dict,就用dict.keys()將其所有的key給列印出來,然後挑你所需要的key往下追蹤。

# print the type of whole data
print(type(data))

Output

<class 'dict'>

取出所有的keys與Values

使用.keys().values().items()分別取出dict的內容,並觀察結果。

逐行列印Youbike的內容

Iterating a dictionary: 下列方法都可以把所有站台的sbi給列印出來,請觀察看看.items()和沒有.items()的用法有何差異。

for k in data["retVal"].keys():
    print(data["retVal"][k]["sbi"])
for k in data["retVal"]:
    print(data["retVal"][k]["sbi"])
for k in data["retVal"].items():
    print(k[1]["sbi"])
for k, v in data['retVal'].items():
    print(k, v["sbi"])

計算每個行政區有多少個youbike站台

area_dict = {}
for key, row in data["retVal"].items():
    if row["sarea"] not in area_dict:
        area_dict[row["sarea"]] = 1
    else:
        area_dict[row["sarea"]] += 1
area_dict

Last updated