iT邦幫忙

0

[已解決]Dictionaries裡存list的value

如題,我想將下方資料將word裡的單字以ll作為分類存成一個list,
並且其key為l+ll為命名

l ll word
1 1 bag
1 1 book
1 1 crayon
1 1 pen
1 2 board
1 2 chair
1 2 clock
1 2 desk
1 4 cat
1 4 dog
1 4 hamster
1 4 parrot
1 5 bear
1 5 lion

以下是我的程式碼

# 開啟 CSV 檔案
with open('fileName.csv', newline='') as csvFile:
    rows = csv.reader(csvFile, delimiter=',')
    # 轉成一個 dictionary, 讀取 CSV 檔內容,將每一列轉成字典
    rows = csv.DictReader(csvFile)
    # 迴圈輸出 每一列
#     for row in rows:
#         print(row['l'],row['ll'], row['word'])
#     print("#################")
    # 使用 dictionary分類
    classification = {}
        
    # 迴圈輸出 每一列
    for row in rows:
        classification.setdefault(["l{0}ll{1}".format(row['l'],row['ll'])],[]).append(row['word'])
        

期望輸出
l1ll1 : [bag,book,crayon,pen]
l1ll2 : [board,chair,clock,desk]
l1ll4 : [cat,dog,hamster,parrot]
l1ll5 : [bear,lion]

但會因 classification.setdefault 導致ValueError: I/O operation on closed file. 和 TypeError: unhashable type: 'list' 的錯誤

懇請各位大大解答,感謝

p39212053 iT邦新手 5 級 ‧ 2019-10-03 08:39:43 檢舉
已解決方法:
將classification.setdefault(["l{0}ll{1}".format(row['l'],row['ll'])],[]).append(row['word'])
其中的 "l{0}ll{1}".format(row['l'],row['ll'])先用key變數存起來
變成
classification.setdefault(key,[]).append(row['word'])

即可解決

2 個回答

1
ccutmis
iT邦高手 9 級 ‧ 2019-10-03 09:53:35
最佳解答

讀入CSV檔並以主次欄位(L+LL)為KEY,
內容欄位(WORD)為VALUE存入DICT物件,
主次欄位(L+LL)相同的內容欄位會存成串列型式
例如['bear','lion'],
個人認為這題對python自學新鮮人來說應該算是蠻有趣的,
且有實務應用上的價值。

樓主有自己找到解答,不過我還是在這邊補充一些個人的作法給樓主及邦友們參考,

fileName.csv檔案內容

l ll word
1 1 bag
1 1 book
1 1 crayon
1 1 pen
1 2 board
1 2 chair
1 2 clock
1 2 desk
1 4 cat
1 4 dog
1 4 hamster
1 4 parrot
1 5 bear
1 5 lion

Demo1 程式部份 (樓主提供的程式碼作一些小改)

import csv
# 開啟 CSV 檔案
with open('fileName.csv', newline='') as csvFile:
	rows = csv.reader(csvFile, delimiter=',')
	rows = csv.DictReader(csvFile)
	classification = {}
		
	# 迴圈輸出 每一列
	for row in rows:
		tmparr=(row["l ll word"].split(" "))
		classification.setdefault("L{0}LL{1}".format(tmparr[0],tmparr[1]),[]).append(tmparr[2])
print(classification)

Demo2 程式部份 (我自己土法鍊鋼的程式碼,不用匯入csv模組)

classification = {}
with open('fileName.csv', 'r',encoding='utf-8') as f:
	csvlines=f.readlines()
	for row in range(1,len(csvlines)):
		tmparr=(csvlines[row].replace('\n','').split(" "))
		classification.setdefault("L{0}LL{1}".format(tmparr[0],tmparr[1]),[]).append(tmparr[2])
print(classification)

Demo1 及 Demo2的 輸出結果都是

{'L1LL1': ['bag', 'book', 'crayon', 'pen'], 'L1LL2': ['board', 'chair', 'clock', 'desk'], 'L1LL4': ['cat', 'dog', 'hamster',
'parrot'], 'L1LL5': ['bear', 'lion']}
0
小魚
iT邦大師 1 級 ‧ 2019-10-03 08:29:36

沒有實作過,
不過看你的錯誤訊息,
是在說你已經把檔案關掉了還試圖操作它,
雖然我看不出檔案是在哪裡關掉的,
也或許你貼出來的程式碼並不完整.

p39212053 iT邦新手 5 級 ‧ 2019-10-03 08:40:39 檢舉

感謝,已解決

我要發表回答

立即登入回答