您好,登錄后才能下訂單哦!
本篇內容主要講解“加速Python編程的小技巧有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“加速Python編程的小技巧有哪些”吧!
1.負索引
人們喜歡使用序列,因為當我們知道元素的順序,我們就可以按順序操作這些元素。在Python中,字符串、元組和列表是最常見的序列數據類型。我們可以使用索引訪問單個項目。與其他主流編程語言一樣,Python支持基于0的索引,在該索引中,我們在一對方括號內使用零訪問第一個元素。此外,我們還可以使用切片對象來檢索序列的特定元素,如下面的代碼示例所示。
>>> # Positive Indexing ... numbers = [1, 2, 3, 4, 5, 6, 7, 8] ... print("First Number:", numbers[0]) ... print("First Four Numbers:", numbers[:4]) ... print("Odd Numbers:", numbers[::2]) ... First Number: 1 First Four Numbers: [1, 2, 3, 4] Odd Numbers: [1, 3, 5, 7]
但是,Python通過支持負索引而進一步走了一步。具體來說,我們可以使用-1來引用序列中的最后一個元素,并向后計數。例如,最后一個元素的索引為-2,依此類推。重要的是,負索引也可以與切片對象中的正索引一起使用。
>>> # Negative Indexing ... data_shape = (100, 50, 4) ... names = ["John", "Aaron", "Mike", "Danny"] ... hello = "Hello World!" ... ... print(data_shape[-1]) ... print(names[-3:-1]) ... print(hello[1:-1:2]) ... 4 ['Aaron', 'Mike'] el ol
2.檢查容器是否為空
容器是指可以存儲其他數據的那些容器數據類型。一些經常使用的內置容器是元組,列表,字典和集合。在處理這些容器時,我們經常需要在執行其他操作之前檢查它們是否包含任何元素。確實,我們可以檢查這些容器的長度,該長度與已存儲項目的數量相對應。當長度為零時,容器為空。下面顯示了一個簡單的示例。
if len(some_list) > 0: # do something here when the list is not empty else: # do something else when the list is empty
但是,這不是最好的Pythonic方式。相反,我們可以簡單地檢查容器本身,它將在容器True包含元素時進行評估。盡管以下代碼向您展示了主要的容器數據類型,但這種用法也可以應用于字符串(即,任何非空字符串都是True)。
>>> def check_container_empty(container): ... if container: ... print(f"{container} has elements.") ... else: ... print(f"{container} doesn't have elements.") ... ... check_container_empty([1, 2, 3]) ... check_container_empty(set()) ... check_container_empty({"zero": 0, "one": 1}) ... check_container_empty(tuple()) ... [1, 2, 3] has elements. set() doesn't have elements. {'zero': 0, 'one': 1} has elements. () doesn't have elements.
3.使用Split()創建字符串列表
我們經常使用字符串作為特定對象的標識符。例如,我們可以使用字符串作為字典中的鍵。在數據科學項目中,字符串通常是數據的列名。選擇多個列時,不可避免地需要創建一個字符串列表。確實,我們可以使用列表中的文字創建字符串。但是,我們必須編寫成對的引號將每個字符串括起來,這對于“懶惰”的人來說有點繁瑣。因此,我更喜歡利用字符串的split()方法來創建字符串列表,如下面的代碼片段所示。
>>> # List of strings ... # The typical way ... columns = ['name', 'age', 'gender', 'address', 'account_type'] ... print("* Literals:", columns) ... ... # Do this instead ... columns = 'name age gender address account_type'.split() ... print("* Split with spaces:", columns) ... ... # If the strings contain spaces, you can use commas instead ... columns = 'name, age, gender, address, account type'.split(', ') ... print("* Split with commas:", columns) ... * Literals: ['name', 'age', 'gender', 'address', 'account_type'] * Split with spaces: ['name', 'age', 'gender', 'address', 'account_type'] * Split with commas: ['name', 'age', 'gender', 'address', 'account type']
如上所示,split()默認情況下,該方法使用空格作為分隔符,并根據字符串創建字符串列表。值得注意的是,當您創建包含某些包含空格的元素的字符串列表時,可以選擇使用其他類型的分隔符(例如,逗號)。
這種用法受到一些內置功能的啟發。例如,當你創建一個元組類,我們可以這樣做:Student = namedtuple(“Student”, [“name”, “gender”, “age”])。字符串列表指定了元組的“屬性”。但是,也可以通過以下方式定義該類來本地支持它:Student = namedtuple(“Student”, “name gender age”)。對于另一個實例,創建一個Enum類支持相同的替代解決方案。
4.三元表達
在許多用例中,我們需要根據條件定義具有特定值的變量,并且我們可以簡單地使用if ... else語句來檢查條件。但是,它需要幾行代碼。如果僅處理一個變量的賦值,則可能需要使用三元表達式,該表達式檢查條件并僅用一行代碼即可完成賦值。此外,它的格式更短,從而使代碼更加簡潔。考慮以下示例。
# The typical way if score > 90: reward = "1000 dollars" else: reward = "500 dollars" # Do this instead reward = "1000 dollars" if score > 90 else "500 dollars"
有時,我們可以從已定義的函數中獲取一些數據,并且可以利用這一點并編寫三元表達式的簡單操作,如下所示。
# Another possible scenario # You got a reward amount from somewhere else, but don't know if None/0 or not reward = reward_known or "500 dollars" # The above line of code is equivalent to below reward = reward_known if reward_known else "500 dollars"
5.帶文件對象的語句
我們經常需要從文件讀取數據并將數據寫入文件。最常見的方法是使用內置open()函數簡單地打開文件,該函數會創建一個我們可以操作的文件對象。
>>> # Create a text file that has the text: Hello World! ... ... # Open the file and append some new data ... text_file0 = open("hello_world.txt", "a") ... text_file0.write("Hello Python!") ... ... # Open the file again for something else ... text_file1 = open("hello_world.txt") ... print(text_file1.read()) ... Hello World!
在前面的代碼片段中,我們從一個文本文件開始,該文件的文本為“ Hello World!”。然后,我們將一些新數據附加到文件中。但是,過了一會兒,我們想再次處理該文件。當我們讀取文本文件時,它仍然具有舊數據。換句話說,附加的文本不包括在文本文件中。
這是因為我們首先沒有關閉文件對象。如果不關閉文件,則無法保存更改。確實,我們可以close()在文件對象上顯式調用該方法。但是,我們可以使用“ with”語句執行此操作,該語句將自動為我們關閉文件對象,如下所示。完成對文件的操作后,我們可以通過訪問文件對象的closed屬性來驗證文件已關閉。
>>> with open("hello_world.txt", "a") as file: ... file.write("Hello Python!") ... ... with open("hello_world.txt") as file: ... print(file.read()) ... ... print("Is file close?", file.closed) ... Hello World!Hello Python!Hello Python! Is file close? True
用更籠統的術語來說,with語句是在Python中使用上下文管理器的語法。上一個示例涉及文件操作,因為這些文件是共享資源,我們負責釋放這些資源。上下文管理器可以幫助我們完成工作。如前所示,文件操作結束后,將使用with語句自動關閉文件。
6.評估多個條件
通常,我們需要評估多個條件。有幾種可能的方案。對于數值,我們可以對同一變量進行多次比較。在這種情況下,我們可以鏈接這些比較。
# Multiple Comparisons # The typical way if a < 4 and a > 1: # do something here# Do this instead if 1 < a < 4: # do somerthing here
在其他一些情況下,我們可以進行多個相等比較,并且可以使用以下in關鍵字進行成員測試。
# The typical way if b == "Mon" or b == "Wed" or b == "Fri" or b == "Sun": # do something here# Do this instead, you can also specify a tuple ("Mon", "Wed", "Fri", "Sun") if b in "Mon Wed Fri Sun".split(): # do something here
另一種技術是使用內置的all()和any()函數用于評估多個條件的功能。具體而言,該all()函數將評估何時迭代中的元素全部為True,因此該函數適合于替換一系列AND邏輯比較。另一方面,該any()函數的計算結果為True當迭代中的任何元素為True,因此適合替換一系列OR邏輯運算。相關示例如下所示。
# The typical ways if a < 10 and b > 5 and c == 4: # do somethingif a < 10 or b > 5 or c == 4: # do something# Do these instead if all([a < 10, b > 5, c == 4]): # do somethingif any([a < 10, b > 5, c == 4]): # do something
7.在函數聲明中使用默認值
在幾乎所有的Python項目中,大多數代碼都涉及創建和調用函數。換句話說,我們不斷處理函數聲明和重構。在許多情況下,我們需要多次調用一個函數。根據不同的參數集,該功能將略有不同。但是,有時一組參數可能比其他一組更常用,在這種情況下,我們在聲明函數時應考慮設置默認值。考慮下面的簡單示例。
# The original form: def generate_plot(data, image_name): """This function creates a scatter plot for the data""" # create the plot based on the data ... if image_name: # save the image ...# In many cases, we don't need to save the image generate_plot(data, None)# The one with a default value def generate_plot(data, image_name=None): pass# Now, we can omit the second parameter generate_plot(data)
要注意的一件事是,如果在設置默認值時要處理可變數據類型(例如列表,集合),請確保使用None而不是構造函數(例如arg_name = [])。由于Python在定義的位置創建函數對象,因此提供的空白列表將被函數對象“卡住”。換句話說,調用函數對象時不會立即創建它。相反,我們將在內存中處理相同的函數對象,包括其最初創建的默認可變對象,這可能會導致意外行為。
8.使用計數器進行元素計數
當我們在列表、元組或字符串中有多個項目時(例如,多個字符),我們經常想計算每項中有多少個元素。為此,可以為此功能編寫一些乏味的代碼。
>>> words = ['an', 'boy', 'girl', 'an', 'boy', 'dog', 'cat', 'Dog', 'CAT', 'an','GIRL', 'AN', 'dog', 'cat', 'cat', 'bag', 'BAG', 'BOY', 'boy', 'an'] ... unique_words = {x.lower() for x in set(words)} ... for word in unique_words: ... print(f"* Count of {word}: {words.count(word)}") ... * Count of cat: 3 * Count of bag: 1 * Count of boy: 3 * Count of dog: 2 * Count of an: 5 * Count of girl: 1
如上所示,我們首先必須創建一個僅包含唯一單詞的集合。然后,我們迭代單詞集,并使用該count()方法找出每個單詞的出現情況。但是,有一種更好的方法可以使用Counter類來完成此計數任務。
>>> from collections import Counter ... ... word_counter = Counter(x.lower() for x in words) ... print("Word Counts:", word_counter) ... Word Counts: Counter({'an': 5, 'boy': 4, 'cat': 4, 'dog': 3, 'girl': 2, 'bag': 2})
該計數器類是在collections模塊中可用的。要使用該類,我們只需創建一個generator:,x.lower() for x in words每個項目都將被計數。如我們所見,Counter對象是類似dict的映射對象,每個鍵對應于單詞列表的唯一項,而值是這些項的計數。
此外,如果我們有興趣找出單詞列表中最頻繁出現的項目,我們可以利用Counter對象的most_common()方法。以下代碼展示了這種用法。我們只需要指定一個整數(N),即可從列表中找出最頻繁的N個項目。附帶說明,該對象還將與其他序列數據一起使用,例如字符串和元組。
>>> # Find out the most common item ... print("Most Frequent:", word_counter.most_common(1)) Most Frequent: [('an', 5)] >>> # Find out the most common 2 items ... print("Most Frequent:", word_counter.most_common(2)) Most Frequent: [('an', 5), ('boy', 4)]
9.按不同的訂單要求排序
在許多項目中,對列表中的項目進行排序是一項普遍的任務。最基本的排序基于數字或字母順序,我們可以使用內置sorted()函數。默認情況下,該sorted()函數將按升序對列表進行排序(實際上,它可以是可迭代的)。如果將reverse參數指定為True,則可以按降序獲得項目。一些簡單的用法如下所示。
>>> # A list of numbers and strings ... numbers = [1, 3, 7, 2, 5, 4] ... words = ['yay', 'bill', 'zen', 'del'] ... # Sort them ... print(sorted(numbers)) ... print(sorted(words)) ... [1, 2, 3, 4, 5, 7] ['bill', 'del', 'yay', 'zen'] >>> # Sort them in descending order ... print(sorted(numbers, reverse=True)) ... print(sorted(words, reverse=True)) ... [7, 5, 4, 3, 2, 1] ['zen', 'yay', 'del', 'bill']
除了這些基本用法外,我們還可以指定key參數,以便可以對復雜項進行排序,例如元組列表。考慮這種情況的以下示例。
>>> # Create a list of tuples ... grades = [('John', 95), ('Aaron', 99), ('Zack', 97), ('Don', 92), ('Jennifer', 100), ('Abby', 94), ('Zoe', 99), ('Dee', 93)] >>> # Sort by the grades, descending ... sorted(grades, key=lambda x: x[1], reverse=True) [('Jennifer', 100), ('Aaron', 99), ('Zoe', 99), ('Zack', 97), ('John', 95), ('Abby', 94), ('Dee', 93), ('Don', 92)] >>> # Sort by the name's initial letter, ascending ... sorted(grades, key=lambda x: x[0][0]) [('Aaron', 99), ('Abby', 94), ('Don', 92), ('Dee', 93), ('John', 95), ('Jennifer', 100), ('Zack', 97), ('Zoe', 99)]
上面的代碼通過利用傳遞給key參數的lambda函數,向我們展示了兩個高級排序的示例。第一個使用降序對項目進行排序,第二個使用默認的升序對項目進行排序。我們要結合這兩個要求,如果考慮使用該reverse參數,則可能會得到一個錯誤的排序樹,因為如果嘗試按多個條件進行排序,則反向參數將適用于所有參數。請參見下面的代碼段。
>>> # Requirement: sort by name initial ascending, and by grades, descending ... # Both won't work ... sorted(grades, key=lambda x: (x[0][0], x[1]), reverse=True) [('Zoe', 99), ('Zack', 97), ('Jennifer', 100), ('John', 95), ('Dee', 93), ('Don', 92), ('Aaron', 99), ('Abby', 94)] >>> sorted(grades, key=lambda x: (x[0][0], x[1]), reverse=False) [('Abby', 94), ('Aaron', 99), ('Don', 92), ('Dee', 93), ('John', 95), ('Jennifer', 100), ('Zack', 97), ('Zoe', 99)] >>> # This will do the trick ... sorted(grades, key=lambda x: (x[0][0], -x[1])) [('Aaron', 99), ('Abby', 94), ('Dee', 93), ('Don', 92), ('Jennifer', 100), ('John', 95), ('Zoe', 99), ('Zack', 97)]
如您所見,通過將reverse參數設置為True或False,都無效。取而代之的是,技巧是取反分數,因此,當您按默認的升序排序時,由于這些值的取反,分數將反向排序。但是,此方法有一個警告,因為取反只能用于數字值,而不能用于字符串。
10.不要忘記defaultdict
字典是一種有效的數據類型,它使我們能夠以鍵值對的形式存儲數據。它要求所有鍵都是可哈希的,存儲這些數據可能涉及哈希表的使用。這種方法允許以O(1)效率實現數據檢索和插入。但是,應注意,除了內置的dict類型外,我們還有其他可用的字典。其中,我想討論defaultdict類型。與內置dict類型不同,defaultdict允許我們設置默認工廠函數,該工廠函數在鍵不存在時創建元素。
>>> student = {'name': "John", 'age': 18} ... student['gender'] ... Traceback (most recent call last): File "<input>", line 2, in <module> KeyError: 'gender'
假設我們正在處理單詞,并且想要將與列表相同的字符分組,并且這些列表與作為鍵的字符相關聯。這是使用內置dict類型的幼稚實現。值得注意的是,檢查dict對象是否具有letter鍵是至關重要的,因為如果鍵不存在,則調用該append()方法會引發KeyError異常。
>>> letters = ["a", "a", "c", "d", "d", "c", "a", "b"] ... final_dict = {} ... for letter in letters: ... if letter not in final_dict: ... final_dict[letter] = [] ... final_dict[letter].append(letter) ... ... print("Final Dict:", final_dict) ... Final Dict: {'a': ['a', 'a', 'a'], 'c': ['c', 'c'], 'd': ['d', 'd'], 'b': ['b']}
讓我們看看如何使用defaultdict編寫更簡潔的代碼。盡管該示例很簡單,但是它只是為我們提供了有關defaultdict類的一些想法,這使我們不必處理字典對象中不存在的鍵。
>>> from collections import defaultdict ... ... final_defaultdict = defaultdict(list) ... for letter in letters: ... final_defaultdict[letter].append(letter) ... ... print("Final Default Dict:", final_defaultdict) ... Final Default Dict: defaultdict(<class 'list'>, {'a': ['a', 'a', 'a'], 'c': ['c', 'c'], 'd': ['d', 'd'], 'b': ['b']})
到此,相信大家對“加速Python編程的小技巧有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。