Python使用collections模塊實現(xiàn)擴展數(shù)據(jù)類
楔子
Python 標準庫提供了一個 collections 模塊,里面提供了很多的數(shù)據(jù)類,在工作中使用這些類能夠簡化我們的開發(fā)。
下面就來看看這個模塊能夠幫助我們做哪些事情?
搜索多個字典
假設當前有 3 個字典:dct1、dct2、dct3,現(xiàn)在要通過 key 查找對應的 value。如果 key 在 dct1 里面存在,那么直接返回,否則從 dct2 里面找。dct2 里面如果不存在,那么從 dct3 里面找。
這個需求該怎么實現(xiàn)呢?
dct1?=?{"a":?1,?"b":?2,?"c":?3} dct2?=?{"d":?4,?"e":?5,?"f":?6} dct3?=?{"e":?7,?"f":?8,?"g":?9} def?get_value_by_key(key): ????if?key?in?dct1: ????????return?dct1[key] ????elif?key?in?dct2: ????????return?dct2[key] ????elif?key?in?dct3: ????????return?dct3[key] ????else: ????????raise?KeyError print(get_value_by_key("b"))??#?2 print(get_value_by_key("d"))??#?4 print(get_value_by_key("f"))??#?6
實現(xiàn)起來非常簡單,但通過 ChainMap 對象可以更方便地做到這一點。
from?collections?import?ChainMap dct1?=?{"a":?1,?"b":?2,?"c":?3} dct2?=?{"b":?4,?"c":?5,?"d":?6} #?將多個字典傳進去, dct?=?ChainMap(dct1,?dct2) #?如果多個字典存在相同的?key,那么返回第一次出現(xiàn)的?key?對應的?value print(dct["b"],?dct["d"]) """ 2?6 """ #?字典的?API?都可以使用 print(dct.items()) """ ItemsView(ChainMap({'a':?1,?'b':?2,?'c':?3},?{'b':?4,?'c':?5,?'d':?6})) """ #?也可以使用?get,如果?key?在所有的字典中都不存在 #?則返回默認值 print(dct.get("k",?333)) """ 333 """ #?ChainMap?對象有一個?maps?屬性,存儲了要搜索的映射列表 #?這個列表是可變的,所以可以直接增加新映射,或者改變元素的順序以控制查找和更新行為。 print(dct.maps) """ [{'a':?1,?'b':?2,?'c':?3},?{'b':?4,?'c':?5,?'d':?6}] """ #?dct.maps?保存了原始的字典,修改?dct.maps?會影響原字典 print(dct1) """ {'a':?1,?'b':?2,?'c':?3} """ dct.maps[0]["a"]?=?11111111 print(dct1) """ {'a':?11111111,?'b':?2,?'c':?3} """ #?同理修改原字典,也會影響?dct.maps
以上就是 ChainMap 對象的用法,當你需要從多個字典中進行搜索的話,它會很有用。
統(tǒng)計可散列的對象
我們經(jīng)常會遇到數(shù)量統(tǒng)計相關的問題,比如有一個序列,計算里面每個元素出現(xiàn)了多少次。一般情況下,我們會這么做。
words?=?["hello",?"world", ?????????"hello",?"beautiful",?"world", ?????????"hello",?"cruel",?"world"] counter?=?{} for?word?in?words: ????if?word?in?counter: ????????counter[word]?+=?1 ????else: ????????counter[word]?=?1 print(counter) """ {'hello':?3,?'world':?3,?'beautiful':?1,?'cruel':?1} """
實現(xiàn)方法沒有任何問題,但通過 Counter 會更方便,并且還提供了更多功能。
from?collections?import?Counter words?=?["hello",?"world", ?????????"hello",?"beautiful",?"world", ?????????"hello",?"cruel",?"world"] #?將序列傳進去即可 counter?=?Counter(words) print(counter) """ Counter({'hello':?3,?'world':?3,?'beautiful':?1,?'cruel':?1}) """ #?Counter?繼承?dict,所以字典的?API?它也是都支持的 counter?=?Counter(hello=3,?world=3,?beautiful=1,?cruel=1) print(counter) """ Counter({'hello':?3,?'world':?3,?'beautiful':?1,?'cruel':?1}) """
Counter 對象還支持動態(tài)更新操作,舉個例子:
from?collections?import?Counter #?Counter?需要接收一個可迭代對象,然后會遍歷它 #?所以結(jié)果就是?a?出現(xiàn)了三次,b?出現(xiàn)了兩次,c?出現(xiàn)了一次 counter?=?Counter("aaabbc") print(counter) """ Counter({'a':?3,?'b':?2,?'c':?1}) """ #?也可以動態(tài)更新,比如又來了一個序列 #?需要和當前的?counter?組合起來進行統(tǒng)計 counter.update("bcd") print(counter) """ Counter({'a':?3,?'b':?3,?'c':?2,?'d':?1}) """ #?可以看到?b?和?c?的值都增加了?1,并且出現(xiàn)了?d #?需要注意的是:update 方法同樣接收一個可迭代對象,然后進行遍歷 #?如果我希望添加一個?key?叫?"bcd"?的話,那么要這么做 counter.update(["bcd"]) print(counter) """ Counter({'a':?3,?'b':?3,?'c':?2,?'d':?1,?'bcd':?1}) """ #?訪問計數(shù),Counter?對象可以像字典一樣訪問 print(counter["a"])?? """ 3 """ #?如果訪問一個不存在的?key,不會引發(fā)?KeyError #?而是會返回?0,表示對象中沒有這個?key print(counter["mmp"])?? """ 0 """ #?還可以計算出現(xiàn)最多的元素,這是用的最頻繁的一個功能 #?統(tǒng)計?string?中前三個出現(xiàn)次數(shù)最多的元素 string?=?"sasaxzsdsadfscxzcasdscxzdfscxsasadszczxczxcsds" counter?=?Counter(string) print(counter) """ Counter({'s':?13,?'c':?7,?'a':?6,?'x':?6,?'z':?6,?'d':?6,?'f':?2}) """ print(counter.most_common(3)) """ [('s',?13),?('c',?7),?('a',?6)] """
Counter 對象還有一個強大的功能,就是它支持算數(shù)操作以及位運算。
from?collections?import?Counter counter1?=?Counter("aabbccc") counter2?=?Counter("bbbccdd") print(counter1)?? print(counter2)?? """ Counter({'a':?2,?'b':?2,?'c':?3}) Counter({'b':?3,?'c':?2,?'d':?2}) """ #?如果?counter1?的元素出現(xiàn)在了?counter2?中 #?就把該元素減去,記?。簻p的是次數(shù) print(counter1?-?counter2)?? """ Counter({'a':?2,?'c':?1}) """ #?a?在?counter1?中出現(xiàn)了?2?次,在?counter2?中沒有出現(xiàn),所以是?a:?2 #?b?在?counter1?中出現(xiàn)了?2?次,在?counter2?中出現(xiàn)?3?次,所以一減就沒有了 #?c?在?counter1?中出現(xiàn)了?3?次,在?counter2?中出現(xiàn)?2?次,所以相減還剩下一次 #?至于?counter1?中沒有的元素就不用管了 #?相加就很好理解了 print(counter1?+?counter2)? """ Counter({'b':?5,?'c':?5,?'a':?2,?'d':?2})? """ #?相交的話,查找公共的元素,并且取次數(shù)出現(xiàn)較小的那個 print(counter1?&?counter2)?? """ Counter({'b':?2,?'c':?2}) """ #?并集的話,取較大的,記住不是相加 #?所以?b?和?c?出現(xiàn)的次數(shù)不會增加,只是取較大的那個 print(counter1?|?counter2)?? """ Counter({'b':?3,?'c':?3,?'a':?2,?'d':?2}) """
以上就是 Counter 的用法,更多的還是統(tǒng)計次數(shù),求 topK。
缺少的鍵返回默認值
很明顯,這是針對于字典的。首先字典也支持這種操作,通過 setdefault 和 get 兩個方法,可以用來獲取 key 對應的 value,并且還能在 key 不存在的時候給一個默認值。
如果 key 存在,兩者會獲取 key 對應的 value;但如果 key 不存在,setdefault 會先將 key 和指定的默認值設置進去,然后再將設置的值返回,而 get 則只會返回默認值,不會進行設置。
d?=?{"a":?1} #?如果?key?存在,直接返回?value print(d.get("a",?0))??#?1 print(d.setdefault("a",?0))??#?1 #?原字典不受影響 print(d)??#?{"a":?1} #?key?不存在,則返回指定的默認值 print(d.get("b",?0))??#?0 #?原字典不受影響 print(d)??#?{"a":?1} #?key?不存在的話,會將?key?和默認值組成鍵值對,設置在字典中 print(d.setdefault("b",?0))??#?0 print(d)??#?{"a":?1,?"b":?0}
指的一提的是,setdefault 是一個非常實用且簡潔的方法,但用的卻不多。我們舉一個例子:
data?=?[ ????("banana",?15),?("banana",?17),?("banana",?22), ????("apple",?31),?("apple",?30),?("apple",?33), ????("orange",?45),?("orange",?47),?("orange",?44), ] #?如果我希望將 data 轉(zhuǎn)成以下格式,該怎么辦呢? """ {'banana':?[15,?17,?22],? ?'apple':?[31,?30,?33],? ?'orange':?[45,?47,?44]} """ def?change_data1(): ????result?=?{} ????for?product,?count?in?data: ????????if?product?not?in?result: ????????????result[product]?=?[count] ????????else: ????????????result[product].append(count) ????return?result print(change_data1()) """ {'banana':?[15,?17,?22],? ?'apple':?[31,?30,?33],? ?'orange':?[45,?47,?44]} """ #?結(jié)果沒問題,但如果用?setdefault?的話會更方便 def?change_data2(): ????result?=?{} ????for?product,?count?in?data: ????????result.setdefault(product,?[]).append(count) ????return?result print(change_data2()) """ {'banana':?[15,?17,?22],? ?'apple':?[31,?30,?33],? ?'orange':?[45,?47,?44]} """
但這個功能也可以通過 defaultdict 完成,該類要求調(diào)用者傳遞一個類型,當 key 不存在時會返回對應類型的零值。
from?collections?import?defaultdict d?=?defaultdict(int) print(d)??#?defaultdict(<class?'int'>,?{}) print(d["a"])??#?0 print(d)??#?defaultdict(<class?'int'>,?{'a':?0}) d?=?defaultdict(tuple) print(d)??#?defaultdict(<class?'tuple'>,?{}) print(d["a"])??#?() print(d)??#?defaultdict(<class?'tuple'>,?{'a':?()}) #?之前的例子就可以這么做 data?=?[ ????("banana",?15),?("banana",?17),?("banana",?22), ????("apple",?31),?("apple",?30),?("apple",?33), ????("orange",?45),?("orange",?47),?("orange",?44), ] result?=?defaultdict(list) for?product,?count?in?data: ????result[product].append(count) #?defaultdict?繼承?dict,支持字典的?API print(dict(result)) """ {'banana':?[15,?17,?22],? ?'apple':?[31,?30,?33],? ?'orange':?[45,?47,?44]} """ #?整個過程就是,key?如果存在,那么獲取?value #?key?不存在,那么將指定類型的零值作為?value(這里是空列表) #?并且返回之前,會先將?key、value?添加到鍵值對中 #?再比如之前的詞頻統(tǒng)計 string?=?"aabbccdddddee" counter?=?defaultdict(int) for?c?in?string: ????counter[c]?+=?1 print(dict(counter)) """ {'a':?2,?'b':?2,?'c':?2,?'d':?5,?'e':?2} """
怎么樣,是不是很方便呢?在實例化 defaultdict 的時候,指定一個類型即可,獲取一個不存在的 key 的時候,會返回指定的類型的零值,并且還會將 key 和零值添加到字典中。
此外 defaultdict 還可以自定義返回值,只需要指定一個不需要參數(shù)的函數(shù)即可。
from?collections?import?defaultdict #?此時的默認值就是?default d?=?defaultdict(lambda:?"default") print(d["aa"])??#?default #?此外還可以添加參數(shù),因為單獨指定了?aa,所以打印的時候以指定的為準 #?如果沒有指定,那么才會得到默認值 d4?=?defaultdict(lambda:?"default",?aa="bar") print(d4["aa"])??#?bar print(d4["bb"])??#?default
那么估計會有人好奇,這是如何實現(xiàn)的呢?其實主要是實現(xiàn)了一個叫做 __missing__ 的魔法方法。字典在查找元素的時候,會調(diào)用 __getitem__,然后在找不到的時候會去調(diào)用 __missing__。但是注意:dict 這個類本身并沒有實現(xiàn) __missing__,所以我們需要繼承自 dict,然后在子類中實現(xiàn)。
class?MyDict(dict): ????def?__getitem__(self,?item): ????????#?執(zhí)行父類的?__getitem__?方法 ????????#?如果?key?不存在,會去執(zhí)行?__missing__?方法 ????????value?=?super().__getitem__(item) ????????#?所以這里的?value?就是?__missing__?方法的返回值 ????????return?value ????def?__missing__(self,?key): ????????self[key]?=?"搞事情?(′ー`?)搞事情" ????????return?self[key] d?=?MyDict([("a",?3),?("b",?4)]) print(d)??#?{'a':?3,?'b':?4} print(d["mmm"])??#?搞事情?(′ー`?)搞事情 print(d)??#?{'a':?3,?'b':?4,?'mmm':?'搞事情?(′ー`?)搞事情'}
都是一些基礎的內(nèi)容了,突然想到了,就提一遍。
雙端隊列
如果你需要維護一個序列,并根據(jù)需求動態(tài)地往序列的尾部添加元素和彈出元素,那么你會選擇什么序列呢?很明顯,如果只在尾部操作,那么列表一定是最合適的選擇。
但如果我們操作的不止是尾部,還有頭部呢?比如往序列的頭部添加和彈出元素,此時雙端隊列就是一個不錯的選擇。
雙端隊列支持從任意一端添加和刪除元素,更為常用的兩種數(shù)據(jù)結(jié)構(即棧和隊列)就是雙端隊列的退化形式,它們的輸入和輸出被限制在某一端。
from?collections?import?deque #?接收一個可迭代對象,然后進行遍歷 d?=?deque("abcdefg") print(d)? """ deque(['a',?'b',?'c',?'d',?'e',?'f',?'g']) """ print(len(d))? """ 7 """ print(d[0])? """ a """ print(d[-1])?? """ g """ #?由于?deque?是一種序列容器,因此同樣支持?list?的操作 #?如:通過索引獲取元素,查看長度,刪除元素,反轉(zhuǎn)元素等等 #?list?支持的操作,deque?基本上都支持 d.reverse() print(d)??#?deque(['g',?'f',?'e',?'d',?'c',?'b',?'a']) d.remove("c") print(d)??#?deque(['g',?'f',?'e',?'d',?'b',?'a'])
deque 還有很多的 API,比如添加元素。
from?collections?import?deque d?=?deque("abc") #?添加元素,可以從兩端添加 d.append("Hello")??#?從尾部添加 d.appendleft("World")??#?也可以從頭部添加 print(d) """ deque(['World',?'a',?'b',?'c',?'Hello']) """ #?還可以使用?insert,?如果范圍越界,自動添加在兩端 d.insert(100,?"古明地覺") print(d) """ deque(['World',?'a',?'b',?'c',?'Hello',?'古明地覺']) """ #?也可以通過extend,extendleft?一次添加多個元素 d?=?deque([1,?2,?3]) d.extend([4,?5,?6]) print(d) """ deque([1,?2,?3,?4,?5,?6]) """ d.extendleft([7,?8,?9]) print(d) """ deque([9,?8,?7,?1,?2,?3,?4,?5,?6]) """ #?注意添加的順序,我們是從左邊開始添加的 #?先添加?7,然后?8?會跑到?7?的左邊,所以是結(jié)果是倒過來的
再來看看刪除元素:
from?collections?import?deque d?=?deque(range(1,?7)) print(d) """ deque([1,?2,?3,?4,?5,?6]) """ #?調(diào)用?pop?方法可以從尾部彈出一個元素 print(d.pop())??#?6 print(d.pop())??#?5 print(d.pop())??#?4 #?pop?是從右端刪除一個元素,popleft?是從左端開始刪除一個元素 #?但如果想?pop?掉指定索引的元素,則只能用?pop?函數(shù),傳入索引值即可 print(d.popleft())??#?1 print(d) """ deque([2,?3]) """ #?注意:deque 和 queue一樣,是線程安全的 #?它們均受?GIL?這把超級大鎖保護,可以不同的線程中進行消費 #?如果想清空里面的元素,可以像?list、dict?一樣,使用?clear?方法 d.clear() print(d)?? """ deque([]) """
最后 deque 還有一個非常有意思的方法,叫 rotate,它是做什么的呢?來看一下。
from?collections?import?deque #?按任意一個方向進行旋轉(zhuǎn),從而跳過某些元素。 # d.rotate(n):n 大于0,從右邊開始取 n 個元素放到左邊 #?n?小于?0,從左邊取?n?個元素放到右邊 d?=?deque(range(10)) print(d)?? """ deque([0,?1,?2,?3,?4,?5,?6,?7,?8,?9]) """ #?從右邊取?2?個元素放到左邊,所以?8?和?9?被放到了左邊 d.rotate(2) print(d)?? """ deque([8,?9,?0,?1,?2,?3,?4,?5,?6,?7]) """ d.rotate(-3) #?從左邊取?3?個元素放到右邊,所以?8、9、0?被放到了右邊 print(d)?? """ deque([1,?2,?3,?4,?5,?6,?7,?8,?9,?0]) """
當然雙端隊列默認是容量無限的,但很多時候我們需要給隊列加上容量限制,如何加呢?
from?collections?import?deque #?限制隊列的大小 #?我們在初始化一個雙端隊列的時候,還可以限制它的大小 d?=?deque("abcdefg",?maxlen=5) #?我們初始化?7?個元素,但是指定最大長度只有?5 #?所以前面兩個元素("a"?和?"b")就被擠出去了 print(d) """ deque(['c',?'d',?'e',?'f',?'g'],?maxlen=5) """ #?當我往前面添加元素的時候,后面的就被擠出去了 #?因為隊列最多只能容納?5?個元素 d.appendleft("Hello") print(d)?? """ deque(['Hello',?'c',?'d',?'e',?'f'],?maxlen=5) """
當你要維護一個從首尾兩端添加、刪除元素的序列時,使用 deque 是一個非常正確的選擇。
比如 asyncio 的鎖 Lock,當獲取鎖時,就會創(chuàng)建一個 Future 對象,并保存在雙端隊列中。
帶有名字的元組
元組的話,我們都是通過索引來獲取元素,但通過索引的話,如果你不手動數(shù)一數(shù),你是不知道該索引會對應哪一個元素的。所以問題來了,可不可以給里面的元素一個字段名呢?我們通過字段名來獲取對應的值不就行啦,沒錯,這就是 namedtuple。
from?collections?import?namedtuple #?傳入名字,和字段 Person?=?namedtuple("Person",?["name",?"age",?"gender"]) person1?=?Person(name="satori",?age=16,?gender="f") print(person1) """ Person(name='satori',?age=16,?gender='f') """ print(person1.name,?person1.age,?person1.gender) """ satori?16?f """ print(person1[0]) """ satori """ #?不僅可以像普通的?tuple?一樣使用索引訪問 #?還可以像類一樣通過?.?字段名訪問 person2?=?Person("satori",?16,?"f") #?注意:這個和普通的元組一樣,是不可以修改的 try: ????person2.name?=?"xxx" except?AttributeError?as?e: ????print(e)??#?can't?set?attribute #?非法字段名,不能使用?Python?的關鍵字 try: ????namedtuple("keywords",?["for",?"in"]) except?ValueError?as?e: ????print(e) ????""" ????Type?names?and?field?names?cannot?be?a?keyword:?'for' ????""" #?如果字段名重復了,會報錯 try: ????namedtuple("Person",?["name",?"age",?"age"]) except?ValueError?as?e: ????print(e) ????""" ????Encountered?duplicate?field?name:?'age' ????""" #?如果非要加上重名字段,可以設置一個參數(shù) Person?=?namedtuple("Person",?["name",?"age",?"age"], ????????????????????rename=True) print(Person)?? """ <class?'__main__.Person'> """ person3?=?Person("koishi",?15,?15) #?可以看到重復的字段名會按照索引的值,在前面加上一個下劃線 #?比如第二個?age?重復,它的索引是多少呢?是?2,所以默認幫我們把字段名修改為?_2 print(person3)?? """ Person(name='koishi',?age=15,?_2=15) """ #?此外我們所有的字段名都保存在?_fields?屬性中 print(person3._fields)?? """ ('name',?'age',?'_2') """
但 namedtuple 還有一個不完美的地方,就是它無法指定字段的類型,所以我們更推薦使用 typing 模塊里的 NamedTuple。
from?typing?import?NamedTuple class?Person(NamedTuple): ????name:?str ????age:?int ????gender:?str p?=?Person("satori",?16,?"f") print(p) """ Person(name='satori',?age=16,?gender='f') """ #?同樣能夠基于索引和字段名來獲取值 print(p[0],?p.name) """ satori?satori """ #?創(chuàng)建類的話,還可以這么創(chuàng)建 Person?=?NamedTuple('Person',?name=str,?age=int,?gender=str) Person?=?NamedTuple( ????'Person',?[("name",?str),?("age",?int),?("gender",?str)] )
更建議使用 NamedTuple。
記住鍵值對順序的字典
從 Python3.6 開始,字典遍歷默認是有序的,但我們不應該依賴這個特性。如果希望字典有序,應該使用 OrderDict 字典子類。
from?collections?import?OrderedDict d?=?OrderedDict() d["a"]?=?"A" d["b"]?=?"B" d["c"]?=?"C" for?k,?v?in?d.items(): ????print(k,?v) """ a?A b?B c?C """ #?此外也可以在初始化的時候,添加元素 print(OrderedDict({"a":?1}))?? """ OrderedDict([('a',?1)]) """ #?相等性,對于常規(guī)字典來說,只要里面元素一樣便是相等的,不考慮順序 #?但是對于OrderDict來說,除了元素,順序也要一樣,否則就不相等 d1?=?{"a":?1,?"b":?2} d2?=?{"b":?2,?"a":?1} print(d1?==?d2)?? """ True """ d1?=?OrderedDict({"a":?1,?"b":?2}) d2?=?OrderedDict({"b":?2,?"a":?1}) print(d1?==?d2)?? """ False """ #?重排,在?OrderDict?中可以使用?move_to_end?方法 #?將某個鍵移動到序列的起始位置或末尾位置來改變順序 d3?=?OrderedDict({"a":?1,?"b":?2,?"c":?3,?"d":?4}) #?表示將?key="c"?的鍵值對移動到末尾 d3.move_to_end("c")?? print(d3)?? """ OrderedDict([('a',?1),?('b',?2),?('d',?4),?('c',?3)]) """ #?表示將?key="c"?的這個鍵值對移動到行首 d3.move_to_end("c",?last=False)?? print(d3)?? """ OrderedDict([('c',?3),?('a',?1),?('b',?2),?('d',?4)]) """ #?從尾部彈出一個元素 print(d3.popitem()) """ ('d',?4) """ #?從頭部彈出一個元素 print(d3.popitem(last=False)) """ ('c',?3) """
使用 OrderDict 要比 dict 更加耗費內(nèi)存,因此在存儲大量鍵值對的時候,思考一下,是否需要保證鍵值對有序。
但在實現(xiàn) LRU 緩存的時候,OrderDict 非常常用,比如某個鍵被訪問了,通過 move_to_end 移到頭部。當緩存滿了的時候,通過 popitem 彈出尾部元素。
以上就是Python使用collections模塊實現(xiàn)擴展數(shù)據(jù)類的詳細內(nèi)容,更多關于Python collections的資料請關注腳本之家其它相關文章!
相關文章
Python Dask庫處理大規(guī)模數(shù)據(jù)集的強大功能實戰(zhàn)
Dask是一個靈活、開源的Python庫,專為處理大規(guī)模數(shù)據(jù)集而設計,與傳統(tǒng)的單機計算相比,Dask能夠在分布式系統(tǒng)上運行,有效利用集群的計算資源,本文將深入介紹Dask的核心概念、功能和實際應用,通過豐富的示例代碼展示其在大數(shù)據(jù)處理領域的強大能力2023-12-12關于Pytorch MaxUnpool2d中size操作方式
今天小編就為大家分享一篇關于Pytorch MaxUnpool2d中size操作方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01Python內(nèi)置函數(shù)——__import__ 的使用方法
本篇文章主要介紹了Python內(nèi)置函數(shù)——__import__ 的使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11如何使用matplotlib讓你的數(shù)據(jù)更加生動
數(shù)據(jù)可視化用于以更直接的表示方式顯示數(shù)據(jù),并且更易于理解,下面這篇文章主要給大家介紹了關于如何使用matplotlib讓你的數(shù)據(jù)更加生動的相關資料,需要的朋友可以參考下2021-11-11Python機器學習NLP自然語言處理基本操作之命名實例提取
自然語言處理(?Natural?Language?Processing,?NLP)是計算機科學領域與人工智能領域中的一個重要方向。它研究能實現(xiàn)人與計算機之間用自然語言進行有效通信的各種理論和方法2021-11-11Python創(chuàng)建文件和追加文件內(nèi)容實例
這篇文章主要介紹了Python創(chuàng)建文件和追加文件內(nèi)容實例,本文同時給出了把標準輸出定向到文件實例,需要的朋友可以參考下2014-10-10