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]
所對應的值就是3
,2
所對應的值就是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資料
用
requests
套件的.get()
獲取該url的回應。將該http request response的文字抽取出來
response.text
,資料型態為str
將抽取出來的文字,我知道他是用json格式存,因此用
json.loads()
將其轉換為python的資料型態,也就是由層層list與dictionary所套疊起來的資料最後一一存取其內容
# 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)
測試出一筆資料的結構
如果偵測出他是一個list,那就取出第0筆資料往下追蹤。
如果偵測出他是一個dict,就用
dict.keys()
將其所有的key給列印出來,然後挑你所需要的key往下追蹤。
# print the type of whole data
print(type(data))
Output
<class 'dict'>
取出所有的keys與Values
使用.keys()
與.values()
與.items()
分別取出dict的內容,並觀察結果。
print(data["retVal"].keys())
Output
dict_keys(['0001', '0002', '0003', '0004', '0005', '0006', '0007', '0008', '0009', '0010', '0011', '0012', '0013', '0014', '0016', '0017', '0018', '0019', '0020', '0021', '0022', '0023', '0024', '0025', '0026', '0027', '0028', '0029', '0030', '0031', '0032', '0033', '0034', '0035', '0036', '0037', '0038', '0039', '0040', '0041', '0042', '0043', '0044', '0045', '0046', '0047', '0048', '0049', '0050', '0051', '0052', '0053', '0054', '0055', '0056', '0057', '0058', '0059', '0060', '0061', '0062', '0063', '0064', '0065', '0066', '0067', '0068', '0069', '0070', '0071', '0072', '0073', '0074', '0075', '0076', '0077', '0078', '0079', '0080', '0081', '0082', '0083', '0084', '0085', '0086', '0087', '0088', '0089', '0090', '0091', '0092', '0093', '0094', '0095', '0096', '0097', '0098', '0099', '0100', '0101', '0102', '0103', '0104', '0105', '0106', '0107', '0108', '0109', '0110', '0111', '0112', '0113', '0114', '0115', '0116', '0117', '0118', '0119', '0120', '0121', '0122', '0123', '0124', '0125', '0126', '0127', '0128', '0129', '0130', '0131', '0132', '0133', '0134', '0135', '0136', '0137', '0138', '0139', '0140', '0141', '0142', '0143', '0144', '0145', '0146', '0147', '0148', '0149', '0150', '0151', '0152', '0153', '0154', '0155', '0156', '0157', '0158', '0159', '0161', '0162', '0163', '0164', '0165', '0166', '0167', '0168', '0169', '0170', '0171', '0172', '0173', '0174', '0175', '0176', '0177', '0178', '0179', '0180', '0181', '0182', '0183', '0184', '0185', '0186', '0187', '0188', '0189', '0190', '0191', '0192', '0193', '0194', '0195', '0196', '0197', '0201', '0202', '0203', '0204', '0205', '0206', '0207', '0208', '0209', '0210', '0211', '0212', '0213', '0214', '0215', '0216', '0217', '0218', '0219', '0220', '0221', '0222', '0223', '0224', '0225', '0226', '0227', '0228', '0229', '0230', '0231', '0232', '0233', '0234', '0235', '0236', '0237', '0238', '0239', '0240', '0241', '0242', '0243', '0244', '0245', '0246', '0247', '0248', '0249', '0250', '0251', '0252', '0253', '0254', '0255', '0256', '0257', '0258', '0259', '0260', '0261', '0262', '0263', '0264', '0265', '0266', '0267', '0268', '0269', '0270', '0271', '0272', '0273', '0274', '0275', '0276', '0277', '0278', '0279', '0280', '0281', '0282', '0283', '0284', '0285', '0286', '0287', '0288', '0289', '0290', '0291', '0292', '0293', '0294', '0295', '0296', '0297', '0298', '0299', '0300', '0301', '0302', '0303', '0304', '0305', '0306', '0307', '0308', '0309', '0310', '0311', '0312', '0313', '0314', '0315', '0316', '0317', '0318', '0319', '0320', '0321', '0322', '0323', '0324', '0325', '0326', '0327', '0328', '0329', '0330', '0331', '0332', '0333', '0334', '0335', '0336', '0337', '0338', '0339', '0340', '0341', '0342', '0343', '0344', '0345', '0346', '0347', '0348', '0349', '0350', '0351', '0352', '0353', '0354', '0355', '0356', '0357', '0358', '0359', '0360', '0361', '0362', '0363', '0364', '0365', '0366', '0367', '0368', '0369', '0370', '0371', '0372', '0373', '0374', '0375', '0376', '0377', '0378', '0379', '0380', '0381', '0382', '0383', '0384', '0385', '0386', '0387', '0388', '0389', '0390', '0391', '0392', '0393', '0394', '0395', '0396', '0397', '0398', '0399', '0400', '0401', '0402', '0403', '0404'])
逐行列印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