python對象引用計數器
前提 (The Premise)
When we deal with data containers, such as tuples and lists, in Python we often need to count particular elements. One common way to do this is to use the count()
function — you specify the element you want to count and the function returns the count.
當我們在Python中處理數據容器(例如元組和列表)時,我們經常需要計算特定元素。 一種常見的實現方法是使用count()
函數-您指定要計數的元素,然后該函數返回計數。
Let’s take a look at some code for its use:
讓我們看一些使用它的代碼:
As you can see above, we used the count()
function with a list of scores.
如上所示,我們將count()
函數與分數列表一起使用。
One thing to note: When the elements specified in the function aren’t included in the list, we’ll get a count of zero, as expected. If we want to count the occurrences of all the elements, we’ll have to iterate them, as shown in the following code snippet:
需要注意的一件事:如果函數中指定的元素未包含在列表中,我們將得到預期的零計數。 如果要計算所有元素的出現次數,則必須對其進行迭代,如以下代碼片段所示:
Several things are worth highlighting in the above:
上面值得強調的幾件事:
To avoid counting elements of the same value, we use the
set()
constructor to convert these iterables to set objects. This means duplicate elements are removed — the for loop will only go over distinct elements to get their correct cumulative counts.為了避免計數相同值的元素,我們使用
set()
構造函數將這些可迭代對象轉換為set對象。 這意味著刪除了重復的元素-for循環將僅遍歷不同的元素以獲得正確的累計計數。The
count()
function doesn’t only work with the list objects, it can also with tuples and strings. More generally, thecount()
function works with sequence data in Python, including strings, lists, tuples, and bytes.count()
函數不僅適用于列表對象,還適用于元組和字符串。 更一般而言,count()
函數可用于Python中的序列數據,包括字符串,列表,元組和字節。
As shown above, we have to use a for loop to iterate the elements to retrieve the counts for each individual element. It’s a bit tedious.
如上所示,我們必須使用for循環來迭代元素以檢索每個單獨元素的計數。 這有點乏味。
Is there another, better way to solve the problem? If you know Python, you should guess that the answer is yes. The Counter
class is specifically designed to count elements in these data structures.
是否有另一種更好的方法來解決該問題? 如果您了解Python,則應該猜測答案是肯定的。 Counter
類專門設計用于對這些數據結構中的元素進行計數。
柜臺類-概述 (The Counter Class — Overview)
The Counter
class is available through the collections
module as part of Python’s standard library. As a subclass of the dict
class, it provides a few highly specialized methods that handle object counting. To create a counter object, you can simply set an iterable to the Counter
class instance constructor, as shown:
Counter
類可作為Python標準庫的一部分通過collections
模塊獲得。 作為dict
類的子類,它提供了一些處理對象計數的高度專業化的方法。 要創建一個計數器對象,您可以簡單地將一個Iterable設置為Counter
類實例構造函數,如下所示:
As you can see at line seven, a Counter
object looks like a dictionary with a series of key-value pairs. Specifically, the keys are the counted elements, while the values are the counters for the corresponding keys. If you want to retrieve the counts for individual items, you can do that just as you work with a dictionary. Some trivial examples are shown below. Notably, if the key doesn’t exist in the Counter
object, the count will be zero.
如您在第七行看到的, Counter
對象看起來像是帶有一系列鍵值對的字典。 具體來說,鍵是被計數的元素,而值是對應鍵的計數器。 如果要檢索單個項目的計數,則可以像處理字典一樣進行。 一些簡單的示例如下所示。 值得注意的是,如果Counter
對象中不存在鍵,則計數將為零。
One critical thing to note is that because of the key-value mapping mechanism, only hashable objects can be tracked by a Counter
object. In Python, immutable objects, such as strings, integers, and tuples are all hashable, while mutable objects, such as lists, sets, and dictionaries are unhashable. A detailed discussion of object hashability is beyond the scope of the present article, and if you’re interested, you can find more information in my previous article on this topic.
需要注意的關鍵一點是,由于鍵值映射機制, Counter
對象只能跟蹤可哈希對象。 在Python中,不可變對象(例如字符串,整數和元組)都是可哈希的,而可變對象(例如列表,集合和字典)則不可哈希。 關于對象散列性的詳細討論超出了本文的范圍,并且如果您有興趣,可以在我上一篇有關該主題的文章中找到更多信息。
The following code shows you a trivial example when we try to use Counter
with unhashable objects — lists
. The error message clearly tells us that Python cannot instantiate a Counter
object for us because lists
are unhashable objects in Python.
以下代碼向您展示了一個簡單的示例,當我們嘗試將Counter
與不可哈希對象一起使用時- lists
。 該錯誤消息清楚地告訴我們,Python無法為我們實例化Counter
對象,因為lists
在Python lists
是不可散列的對象。
確定最頻繁的項目 (Determine the Most Frequent Items)
Often, we need to know what the frequently occurring items in a data container (e.g., lists and tuples) are. Before we see the solution with the Counter
object, let’s see how to achieve this functionality using some tedious code:
通常,我們需要知道數據容器(例如列表和元組)中經常出現的項目是什么。 在看到帶有Counter
對象的解決方案之前,讓我們看一下如何使用一些乏味的代碼來實現此功能:
As shown above, we first needed to use the list’s count()
method to count each of the unique items in the list and save the counting result to a dictionary. Next, we had to use the built-in max()
function to sort the items of the dictionary by specifying the sorting key to use the value of each key-value pair. Certainly, this way works but it’s not the idiomatic way, in which case, we should consider using Counter
.
如上所示,我們首先需要使用列表的count()
方法對列表中的每個唯一項進行計數,并將計數結果保存到字典中。 接下來,我們必須使用內置的max()
函數通過指定排序鍵以使用每個鍵值對的值來對字典中的項進行排序。 當然,這種方法可行,但不是慣用的方法,在這種情況下,我們應該考慮使用Counter
。
As shown above, the first impression that you should have is how concise the code is compared to the non-idiomatic implementation of this functionality. It’s all because the Counter
object has a handy most_common()
method, which quickly pulls the needed information for us — the most frequently occurring item and its associated count. Actually, to give us more flexibility, we have the option to find out an arbitrary number of the most frequently occurring items, as shown below.
如上所示,您應該獲得的第一印象是將代碼的簡潔程度與該功能的非慣用實現相比。 這是因為Counter
對象有一個方便的most_common()
方法,該方法可以為我們快速獲取所需的信息-最頻繁出現的項目及其相關計數。 實際上,為給我們更大的靈活性,我們可以選擇找出任意數量的最頻繁出現的項目,如下所示。
Please note that when you don’t specify any numbers in the most_common()
method, all the elements will be returned as a list in the descending order of the counts. This descending order can be very useful, which allows us to retrieve the item with the least count, as shown below.
請注意,當您未在most_common()
方法中指定任何數字時,所有元素都將按照計數的降序作為列表返回。 降序可能非常有用,這使我們可以檢索數量最少的商品,如下所示。
更新計數器對象 (Update the Counter Object)
Previously, we saw that the Counter
object is used to count the elements in a list. But what if we get another list and want to update the original Counter
object without creating a new one?
之前,我們看到了Counter
對象用于對列表中的元素進行計數。 但是,如果我們得到另一個列表并想要更新原始的Counter
對象而不創建一個新的對象,該怎么辦?
One possible solution is to take advantage of a Counter
object, implementing the mapping protocol such that we can update each key’s value accordingly. Notably, if the key doesn’t exist in the original Counter
object, unlike the built-in dict
data type, a KeyValue
exception won’t be raised, because by default, a missing key in a Counter
object has a value of 0
, as we saw with accessing individual items.
一種可能的解決方案是利用Counter
對象,實現映射協議,以便我們可以相應地更新每個鍵的值。 值得注意的是,如果鍵不存在于原始Counter
對象中(與內置dict
數據類型不同),則不會引發KeyValue
異常,因為默認情況下, Counter
對象中缺少的鍵的值為0
,正如我們在訪問單個項目時看到的那樣。
There’s a more elegant way to update the original Counter
object — use the Counter
’s update()
method. Don’t confuse this update()
method with the dict’
s update()
method, which updates the values of matching keys. Instead, the Counter
’s update()
method will internally generate the counts for the items and use these counts to update the original Counter
object, as shown in the code snippet below.
有一種更優雅的方式來更新原始的Counter
對象-使用Counter
的update()
方法。 不要將此update()
方法與dict'
的update()
方法混淆,后者會更新匹配鍵的值。 相反, Counter
的update()
方法將在內部生成項目的計數,并使用這些計數來更新原始的Counter
對象,如下面的代碼片段所示。
數學運算 (Mathematical Operations)
The name of the Counter
class is informational, which tells you that it counts for us. As we’ve seen, we can update the counts with the update()
method. More broadly, when we have multiple Counter
objects, we can have addition and subtraction operations with them. When we add Counter
objects, the counts for the elements are merged.
Counter
類的名稱是參考性的,它告訴您它對我們很重要。 如我們所見,我們可以使用update()
方法更新計數。 更廣泛地說,當我們有多個Counter
對象時,我們可以對其進行加減運算。 當我們添加Counter
對象時,元素的計數將合并。
The following code shows you such operation, which should be self-explanatory:
下面的代碼向您展示了這樣的操作,這應該是不言而喻的:
In a similar fashion, we can subtract one Counter
object from another Counter
object using the minus operator, as shown below.
以類似的方式,我們可以使用減號運算符從另一個Counter
對象中減去一個Counter
對象,如下所示。
In the above code, one thing to note is that when we use the subtraction operator, the resulting Counter
object will only include those key-value pairs with positive counts. This behavior is different from Counter
’s method subtract()
, which will also include negative counts. Also, as noted previously, when a Counter
doesn’t contain the elements, they have a count of zero by default. With these two things in mind, let’s see how the subtract()
method works with Counter
objects.
在上面的代碼中,需要注意的一件事是,當我們使用減法運算符時,所得的Counter
對象將僅包括具有正計數的那些鍵值對。 此行為不同于Counter
的方法subtract()
,該方法還將包括負數。 另外,如前所述,當Counter
不包含元素時,默認情況下它們的計數為零。 牢記這兩點,讓我們看一下subtract()
方法如何與Counter
對象一起工作。
As you can see, the resulting Counter
object includes several elements with negative counts. Another thing to note is that the subtract()
method changes the counts in-place, which means that the subtract()
method returns None
and it changes the original Counter
object’s counts.
如您所見,生成的Counter
對象包含多個帶有負計數的元素。 還要注意的另一件事是subtract()
方法就地更改了計數,這意味著subtract()
方法將返回None
并且它會更改原始Counter
對象的計數。
集樣操作 (Set-Like Operations)
In addition to the support of mathematical operations, there are two set-like operations available to the Counter
objects: union
and intersection
. To create a “union” of two Counter
objects, you simply use the OR operator (i.e., the vertical bar) to connect them. The union operation will be carried out by using the maximal counts of each matching key in the resulting Counter
object. A trivial example is shown below:
除了支持數學運算外, Counter
對象還可以使用兩種類似集合的運算: union
和intersection
。 要創建兩個Counter
對象的“聯合”,只需使用OR運算符(即,豎線)將它們連接。 聯合操作將通過使用結果Counter
對象中每個匹配鍵的最大計數來執行。 一個簡單的示例如下所示:
To create an “intersection” of two Counter
objects, you’ll simply use the AND operator (i.e. the &
sign) to connect them. The intersection operation will be carried out by using the minimal counts of each matching key in the resulting Counter
object. A trivial example is shown below.
要創建兩個Counter
對象的“交集”,只需使用AND運算符(即&
符號)將它們連接起來。 將通過使用結果Counter
對象中每個匹配鍵的最小計數來執行相交操作。 一個簡單的例子如下所示。
其他功能亮點 (Highlights of Other Features)
In the previous sections, we learned that we can create Counter
objects from iterables, including tuples, lists, and strings. As mentioned previously, the Counter
class is a subclass of the built-in dict
class, so we can use instantiation methods that are available to the dict
class. Some examples are shown below with accompanying explanatory comments:
在上一節中,我們了解了可以從可迭代對象(包括元組,列表和字符串)創建Counter
對象。 如前所述, Counter
類是內置dict
類的子類,因此我們可以使用dict
類可用的實例化方法。 下面顯示了一些示例,并附有解釋性注釋:
We’ve seen that the counts of the Counter
objects are derived from counting or mathematical operations. We can directly set the count of particular elements if it’s an applicable usage. In addition, we can remove the elements from the Counter
object, just like removing a key-value pair from a dict
object. See below for such usages:
我們已經看到, Counter
對象的計數是從計數或數學運算得出的。 如果可以使用的話,我們可以直接設置特定元素的數量。 另外,我們可以從Counter
對象中刪除元素,就像從dict
對象中刪除鍵/值對一樣。 參見下面的用法:
Another useful method of a Counter
object is the elements()
method, which creates an iterator of all items with each having the desired occurrences matching its count. This method is particularly handy for iterating different items of known numbers.
Counter
對象的另一個有用的方法是elements()
方法,該方法創建所有項目的迭代器,每個項目都具有與其計數匹配的期望出現次數。 該方法對于迭代已知數字的不同項特別方便。
結論 (Conclusions)
In this article, we reviewed the interesting Counter
class for counting hashable objects in sequences, including tuples, lists, and strings. As a subclass of the dict
data type, we can create Counter
objects from the sequences as well as mapping and keyword arguments, just as regular dict
objects. The Counter
object is highly flexible in that you can manipulate the counts of these elements as you want. You can even update, merge, and intersect Counter
objects.
在本文中,我們回顧了有趣的Counter
類,用于對序列中的可哈希對象進行計數,包括元組,列表和字符串。 作為dict
數據類型的子類,我們可以像常規dict
對象一樣,從序列以及映射和關鍵字參數中創建Counter
對象。 Counter
對象具有高度的靈活性,因為您可以根據需要操縱這些元素的計數。 您甚至可以更新,合并和相交Counter
對象。
Most interestingly, it has the most_common()
method, which allows us to find out the most frequent items with one line of code. It’s also possible to find out the least frequent items by taking advantage of the most_common()
method, which sorts the items in descending order, allowing us to retrieve the last item for the least common item.
最有趣的是,它具有most_common()
方法,該方法使我們可以用一行代碼找出最頻繁的項目。 也可以利用most_common()
方法找出最不頻繁的項目,該方法以降序對項目進行排序,從而使我們能夠檢索最不常見項目的最后一個項目。
Thanks for reading.
謝謝閱讀。
翻譯自: https://medium.com/better-programming/count-items-in-python-with-the-help-of-counter-objects-c08d8d486e45
python對象引用計數器
本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。 如若轉載,請注明出處:http://www.pswp.cn/news/388015.shtml 繁體地址,請注明出處:http://hk.pswp.cn/news/388015.shtml 英文地址,請注明出處:http://en.pswp.cn/news/388015.shtml
如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!