你能發現這段 Python 代碼中的 bug 嗎?

點擊鏈接瞭解詳情

img


【CSDN 編者按】大家一起來找 Bug。

原文鏈接:https://dwrodri.gitlab.io/can-you-spot-the-bug-in-this-python-code/

本文已獲作者授權,未經允許,禁止轉載!

作者 | Derek Rodriguez

譯者 | 彎月

責編 | 夏萌

出品 | CSDN(ID:CSDNnews)

最近,在解析文本時,我遇到了一個十分有趣的問題。在深入探討之前,讓我先來介紹一下背景故事。我的任務是分析文本文件中的一些以逗號分隔的數據,如下所示:

img

這個文本文件包含若干寬度可變的十六進制值,每行至少三個字段。我只關心第一個和第三字個段。在我看來,分析工作可分爲三步:

  1. 循環讀取每一行數據;
  2. 利用逗號將數據分解成一個列表;
  3. 選取第一個和第三個元素,並將它們轉換爲整數。

看似很簡單,我可以使用 pandas DataFrame 編寫幾行代碼就夠了。

下面是我編寫的代碼:

img

你發現 bug 了嗎?反正我沒看出來。下面,我來詳細解釋一下這段代碼,並深入剖析我究竟錯在哪兒了。

img

代碼詳解

CSV文件是列表的列表

我簡單地認爲,CSV 數據就是列表的列表。因此,我可以將各個元素視爲嵌入列表。我從網上的一篇帖子中找到了讀取嵌入列表的代碼,然後複製粘貼:

nested_lists = [[1,2,3],[4,5,6],[7,8,9]]flattened_list = [element for sublist in nested_lists for element in sublist]

以前我曾接觸過 C 和 C++,之後才學習了 Python,因此在學習嵌套推導式時,我感覺 Python 只是機器可以理解的僞代碼。這個嵌套列表會生成以下字節碼:

img

然後,我一些自己的代碼進行擴展,最終得到了以下代碼:

img

img

錯誤

事實證明,Python 無法按照我的想象將可迭代的文本分解與推導式結合起來,你必須把 .split(",") 調用放在另一個列表中:

img

這讓我有點傷腦筋,因爲 .split(",") 本身就是一個列表,將它打包到另一個列表中,豈不變成了雙重嵌套列表?我不太明白。我嘗試通過編譯器瀏覽器尋找答案。下圖展示了正確的生成器表達式與我編寫的代碼之間的差異:

img

你看出問題所在了嗎?代碼中的問題在於,在分解文本之前,.split() 的返回值是迭代器。我不確定,但我相信這關係到最初提出列表推導式的建議時確立的實現細節。

最後,我在 CPython 的貢獻者 Crowthebird 的幫助下解決了這個問題,他演示了在不使用推導式的情況下重寫代碼的問題。

錯誤的寫法:

img

正確的寫法:

img

img

這個問題可以得到解決嗎?

這實際上是因爲我對 Python解釋器的理解有錯,解釋器本身沒有問題。我不認爲按照我的理解修改語言會更好,因爲如此很難區分在嵌套的情況下容器何時應該解構,何時應該重用,此外列表推導式會返回元組,而 PEP 202 規定不允許。

img

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章