昨天我們測試過最基本的搜尋功能沒問題,但是多測試幾次後發現,有時候會出現很多個一樣的題目,是轉換出錯了?還是題目重複出現了?
在轉換pdf的時候,已經加入一些條件避免出錯了,先檢查是不是題目重複出現,在題目後面加上考試時間檢查。
<p><strong>題目:</strong> {{ result.question_text }} {{ result.exam_date }}</p>
發現原來是不同考試時間出現一樣的題目,那重複的題目怎麼辦?考古題裡題目重複出現代表這可能是常考題,如果未來想要分析考題,希望可以把來源檔案合併,只保留一個題目。
// 希望合併後的樣子,考試時間和來源檔案基本相同改為只保留來源檔案
"題目": "對於常用的醫學詞彙及編碼標準的敘述,下列何者錯誤?",
"選項": [
"ICD是世界衛生組織應用於收集和處理罹病及死亡統計的編碼系統",
"DRGs是醫學詞彙系統中完整性、彈性及表達力之首選",
"LOINC是應用在實驗室檢驗的代碼標準",
"UMLS是美國醫學圖書館(NLM)所建立的醫學詞彙標準"
],
"答案": "DRGs是醫學詞彙系統中完整性、彈性及表達力之首選",
"來源書籍": "醫學資訊管理學",
"頁次": "68",
"來源檔案": [
"2024年4月.pdf",
"2024年11月.pdf",
"2023年11月.pdf"
]
網路上有很多方法可以去除重複資料,其中最簡單的方法是用set,但我需要保留重複題目的來源檔案,所以最後我參考了如何在 Python 中有效使用字典進行去重:2025 最新教學,用dict配合set來處理。
dict是什麼?
dict(dictionary)是一種python內建資料結構,由key來索引,key可以是數字、字串或是任何不可變的型態。
def merge_questions(json_path):
with open(json_path, 'r', encoding='utf-8') as f:
data = json.load(f)
merged = {} # dict
for q in data:
key = (q["題目"], q["答案"]) # 以題目和答案作為key,這裡的資料類型是tuple,是不可變的
if key not in merged:
merged[key] = {
"題目": q["題目"],
"選項": q["選項"],
"答案": q["答案"],
"來源書籍": q.get("來源書籍", ""),
"頁次": q.get("頁次", ""),
"來源檔案": set([q.get("來源檔案")]) if q.get("來源檔案") else set(),
}
else:
# 出現重複題目,合併題目只保留來源檔案。
if q.get("來源檔案"):
if isinstance(q["來源檔案"], list):
merged[key]["來源檔案"].update(q["來源檔案"])
else:
merged[key]["來源檔案"].add(q["來源檔案"])
# 把set轉回list
merged_list = []
for v in merged.values():
v["來源檔案"] = list(v["來源檔案"])
merged_list.append(v)
# 重新寫入json
with open(json_path, 'w', encoding='utf-8') as f:
json.dump(merged_list, f, ensure_ascii=False, indent=4)
print(f"合併完成,共 {len(merged_list)} 題,已輸出至 {json_path}")
tuple是什麼?
tuple通常用來儲存異質的元素序列,可以同時儲存不同的資料結構,不可變。