1. 程式人生 > 其它 >3 個很酷的 Python 庫,可以節省您的時間和精力

3 個很酷的 Python 庫,可以節省您的時間和精力

嘿,看,我正在使用 Python 徽標。再次。真的只是為了好看的縮圖。

嘿,尊貴的讀者。你好嗎?好的!很高興聽到。你知道,我真的很關心你的幸福。這就是我寫這篇文章的原因!上一次,我們討論了一些用 Python 編寫高效能程式碼的技巧。今天我們將討論在編寫程式碼時使用開源庫來節省時間。這不是因為懶惰而做的事情;這是必須要做的事情,因為它會為您節省大量時間、精力和心痛。

當你發現你的小精靈陷入了一些機械問題時,花點時間想想這個問題是否已經在圖書館中解決了。如果是,那麼很可能已有數千人在使用它。這意味著它經過實戰考驗並且廣為人知——比你自己可能實現的還要多。

不僅如此,這些庫還非常酷且易於使用。我把最好的留到最後,所以,你知道。分叉他們的“平均閱讀時間”。

JMES路徑

發音為“James-Path”,這是一個幫助查詢 JSON 的庫。超級簡單。你可以在這裡找到它!

秒情況:您正在處理一個非常深的 JSON 文件或字典。有時鑰匙可能不在那裡。讓我們假設它看起來像這樣:

test_dictionary = {   'level_1': {   'level_2_a': {   'level_3_a': 'some_string'   },   'level_2_b': {   'level_3_b': 'a_different_string'   }   }  }

現在讓我們假設低於 1 級的任何級別都可以為空。然後,如果您想安全地到達最深處,則必須執行以下操作:

level_3_a = test_dictionary.get('level_1', {}).get('level_2_a', {}).get('level_3_a', '')

這很糟糕。這是醜陋的程式碼:難以閱讀,並且如果有些事不對的地方,搞清楚什麼地方出了錯很爛。

相反,讓我們嘗試 JMESPath:

表示式 = jmespath.compile('level_1.level_2_a.level_3_a') 結果 = expression.search(test_dictionary)

JMESPath 使我們能夠訪問我們渴望的 JSON 或字典物件的那種“JavaScript 風格”物件訪問。它使程式碼更簡單,更易於測試。它也是安全的——如果任何路徑不存在,JMESPath 的搜尋函式將返回 None 而不是爆炸。節省時間和頭痛,並使用 JMESPath 解析 JSON 和深度字典。

屈折

Inflection 是一個基於 Ruby 的庫。它可以幫助您處理您的字串,因為字串處理邏輯可能難以編寫,並且您可能第一次錯過了很多極端情況。你可以在這裡找到它!

讓我們來看看一些情況,好嗎?

秒ituation:您有一組單詞想要轉換為文章或書籍的標題。它們來自隨機來源,而且都很醜陋,而且並不完全是標題形式。

words = {'the_last_mimzy', 'The-Return-Of-The-King', 'ConanTheBarbarian'}

嘗試編寫自定義程式碼來檢測這些亂七八糟的標題中的缺陷將非常耗時並且有很多邊緣情況,尤其是當標題數量或您從中提取的來源數量擴大時。將其解除安裝到拐點:

words = {'the_last_mimzy', 'The-Return-Of-The-King', 'ConanTheBarbarian'}  titleized_words = [inflection.titleize(word) for word in words]  print(titleized_words)>>> [《最後的傻瓜》、《王者歸來》、《野蠻人柯南》]

我們不是需要大量測試的數十行(甚至數百行,取決於您的資料的髒程度)程式碼,而是在一行中解決了我們的問題。不錯,對吧?

秒情況:您有要使用的另一種語言或系統生成的變數或資料點的名稱,但您需要它們符合 PEP 標準,也就是說,您需要將它們放在蛇形外殼中。也就是說,假設您有一些名稱如下的資料點:

外國名字 = {'SystemMemoryUsage', 'systemCPU', 'webContainerCGroup'}

就像在我們的“電影/書名”情況下,為了自己做這件事,你需要為這些編寫幾個解析器,即使這樣,還要編寫幾個測試,以及大量的極端情況。相反,將其解除安裝到拐點:

Foreign_names = {'SystemMemoryUsage', 'systemCPU', 'webContainerCGroup'}snake_cased_words = [inflection.underscore(name) for name in foreign_names]列印(snake_cased_words) >>> ['system_memory_usage','system_cpu','web_container_c_group']

完美,正是我們所需要的!我們不必進行大規模的字串格鬥,在那裡我們將字串分塊,降低它們,等等……只需一個函式呼叫,生活就很好。

這兩個例子說明了屈折可以節省您的時間。這個庫還有很多用途。這是一個小型圖書館——你應該檢視這裡的文件以獲得更多關於如何使用它的想法!

更多itertools

我答應過最好的。如果在 JSON 解析和字串轉換上節省時間不會讓您感到興奮,那麼我為您準備了一些東西。more-itertools 是一個嚴重的重擊者,任何時候當你在迭代列表、集合或其他 Python 可迭代物件時,你應該停下來看看你的問題是否已經被 more-itertools 解決了。真的有那麼強大您可以在此處找到來源。more-itertools 有幾類功能可以幫助您程式設計,我將演示一些。

讓我們開始處理幾種情況!(我有三個,但第三個有點混亂,所以我把它從文章中砍掉了。不過程式碼仍在要點中。你可能會喜歡它。)

秒ituation:您有一個字典列表,每個字典都有一個共同的鍵,並且該鍵是重複的(例如: id )。您想根據那個通用的重複鍵將其拆分為多個列表。所以,你有這樣的事情:

sample_chunkable_list_of_dictionaries = [   {'id': '1', 'datapoint': 'datapoint_1_1'},   {'id': '1', 'datapoint': 'datapoint_1_2'},   {'id': '1', 'datapoint ': 'datapoint_1_3'},   {'id': '1', 'datapoint': 'datapoint_1_4'},   {'id': '2', 'datapoint': 'datapoint_2_1'},   {'id': '2 ', 'datapoint': 'datapoint_2_2'},   {'id': '2', 'datapoint': 'datapoint_2_3'},   {'id': '2', 'datapoint': 'datapoint_2_4'},   {'id ': '3', 'datapoint': 'datapoint_3_1'},   {'id': '3', 'datapoint': 'datapoint_3_2'},   {'id': '3', 'datapoint': 'datapoint_3_3'} ,   {'id': '3', 'datapoint': 'datapoint_3_4'},  ]

看看“id”鍵是如何通用的,並且可以重複?讓我們把它拆分成一個列表列表,每個列表只包含原始條目中具有相同 id 的條目。我們需要做的就是使用 itertools 中的 split_when 函式,並提供一個比較函式:

split_into_chunks = list(   more_itertools.split_when(   sample_chunkable_list_of_dictionaries, lambda x , y : x ['id'] != y ['id']   )   )

這裡的格式會變得非常難看,所以我將向您展示結果的影象:

使用 more-itertools 的 split_when 函式

正是我們正在尋找的 - 很好地分割槽。我試著自己寫這個程式,它變得非常難看,非常快。必須跟蹤列表中的位置是一件痛苦的事情,而且您會招致嚴重的逐一錯誤和極端情況。幫自己一個忙,只需使用 split_when 和庫中可用的類似功能。

這是 more-itertools 的資料分組功能之一,當您的資料不太整潔時,當您想要分割槽等時,它還有更多功能。檢查一下。

秒情況:您有多個列表想要合併,但您需要合併列表以將它們的“優先順序”保持在一起——您需要迴圈合併它們。您可以輕鬆編寫此程式碼,它可能看起來像這樣:

寫我自己的交錯

嘿,它是遞迴的!它有效!如果我將它與一些很酷的值一起使用,我們就會得到我們期望的結果:

need_interleaving = [   [1, 3, 5],   [2, 4, 6],   [10, 11, 12, 13]  ]列印(hand_rolled_interleave(need_interleaving))>>> [1, 2, 10, 3, 4, 11, 5, 6, 12, 13]

有幾個問題。首先,它是遞迴的,嘗試閱讀時會立即感到困惑。其次,它相當複雜,資料結構和理解不斷變化。第三,它在大規模上是緩慢的。我可以使用一種稱為 interleave_longest 的方法(以確保我們在用完一個可迭代物件後不會停止),而不是在一個很棒的單行中:

need_interleaving = [   [1, 3, 5],   [2, 4, 6],   [10, 11, 12, 13]  ]# * 是一個擴充套件運算子——它讓我一次傳遞所有 列表 print(list(more_itertools.interleave_longest(*need_interleaving))>>> [1, 2, 10, 3, 4, 11, 5, 6, 12, 13]

涼爽的!所以程式碼不是遞迴的,也不復雜或難以閱讀。但是效能呢?讓我們試一試吧。

(venv) mydriasis@akkad:~/Desktop/article-code/oss-libs$ python more-itertools-test.py  Interleave 10 個長度為 100 的列表每個需要 0.0000069141ms 和 more_itertools  Interleave 10 個長度為 100 的列表每個需要 0.0000069141ms ms 與手卷交錯

看哪,我愚蠢的手卷方法比 itertools 的時間長一百倍。此外,因為它是遞迴的,所以它不能擴充套件。如果列表長於 Python 的最大遞迴深度,這隻會以 RecursionError 爆炸。

看?使用圖書館是值得的。這意味著我們不必自己提出常規實現,或調整遞迴限制。這是 more-itertools 的組合功能之一,還有很多其他功能。

歸根結底,我真的被 more_itertools 驚豔到了。它有很多我可以看到自己一直在使用的功能,而且它們可能比我能寫的任何東西都更有效率。說實話,我不是一個比71 位專職 Python 工程師更好的程式設計師。

每個程式設計師都需要停止做這 7 件事

結論

好吧,我們又來了,你和我。在另一篇文章的結尾,你肯定讀了這麼多。也許你喜歡這個概述。也許你學到了一些東西。也許您最終會使用 JMESPath,因為解析 JSON 很糟糕。或者,您可能在 30 秒內退出了,因為您看到了程式碼塊的頂部,它讓您失望了。不管怎樣,我希望你喜歡。與往常一樣,您可以在絕妙的gist 中找到本文的示例程式碼。我一直……嗯,程式設計師。我們下次會在您不想閱讀但由於標題吸引人的情況下仍然閱讀的文章中與您見面