Python CollectionsモジュールのCounter
Collectionsモジュールのカウンタの使い方と実装原理については、pythonの正式に複写する.を参照してください.
Counter内部実装原理
1.オブジェクトの作成
Counterはdictを継承するクラスで、hashable項目をカウントします.
したがってdictには、必要に応じてcounterクラスを上書きまたは展開する属性もあります.Counter Classの味(?)2番目のディレクトリで、追加したオーバーシュートまたはオーバーシュート方法について説明します.
以前、Counterクラスは
カウントされた各オブジェクトの数がCounterクラスの主要な役割であると考える場合は、各関数がなぜこんなに誇張されているのかを自然に理解できます.代表的な誇張事例をいくつか見てみましょう
update
上の
ここでのupdateはdictのupdateと似ていますが、追加したキーが各count値を置換していない点が異なります.これは、replaceよりも既存のcount値をcountクラスに追加する方が直感的であるためです.△この単語は最終的に何回出てきたのですか.)
実装ロジックでは、dictionary形式で指定されたパラメータが既存のcountに追加され、list形式で指定された場合、
1つの関数で、出現回数が最も多い要素から出現回数が最も多いn番目の要素を返します.
nがない場合は、出現回数の降順で並べ替え、nがある場合はheapqを使用します.
dictの作成時には、
文字列sが小文字(「a」から「z」)からなり、使用頻度が最も高い文字を返すソリューション関数を実現します.
ただし、最大2文字以上のアルファベットを使用すると、アルファベット順に文字列が返されます.
リファレンス🚩
上記の例を少し修正して、特定のアルファベットの順序を早めたい場合は、どうすればいいですか?
この場合、単純呼
△もっといい意見があれば、教えてください.😀)
「コードは次のとおりです.」d'優先度の高い例.
Counter内部実装原理
1.オブジェクトの作成
Counterはdictを継承するクラスで、hashable項目をカウントします.
したがってdictには、必要に応じてcounterクラスを上書きまたは展開する属性もあります.Counter Classの味(?)2番目のディレクトリで、追加したオーバーシュートまたはオーバーシュート方法について説明します.
class Counter(dict):
...
カウンタオブジェクトは、さまざまなパラメータで作成できます.c = Counter()
# 비어있는 Counter
c = Counter('gallahad')
# iterable로부터 Counter를 생성
c = Counter({'a': 4, 'b': 2})
# mapping으로부터 Counter 생성
c = Counter(a=4, b=2)
# 위와 동일한 결과로, keyword args로 생성
これは、Counterクラスのinit関数を表示するときに、次のパラメータが実装されるためです. def __init__(self, iterable=None, /, **kwds):
super().__init__()
self.update(iterable, **kwds)
2.書き換えカウンタ以前、Counterクラスは
dict
を継承し、上書きまたは拡張関数を有していた.カウントされた各オブジェクトの数がCounterクラスの主要な役割であると考える場合は、各関数がなぜこんなに誇張されているのかを自然に理解できます.代表的な誇張事例をいくつか見てみましょう
update
上の
__init__
のupdate
関数をもっと詳しく見てみましょう.ここでのupdateはdictのupdateと似ていますが、追加したキーが各count値を置換していない点が異なります.これは、replaceよりも既存のcount値をcountクラスに追加する方が直感的であるためです.△この単語は最終的に何回出てきたのですか.)
実装ロジックでは、dictionary形式で指定されたパラメータが既存のcountに追加され、list形式で指定された場合、
_count_elements
関数を使用して各要素の出現回数が計算されます. def update(self, iterable=None, /, **kwds):
if iterable is not None:
if isinstance(iterable, _collections_abc.Mapping):
if self:
self_get = self.get
for elem, count in iterable.items():
self[elem] = count + self_get(elem, 0)
else:
# fast path when counter is empty
super().update(iterable)
else:
_count_elements(self, iterable)
if kwds:
self.update(kwds)
_count_elements
関数は、このカウンタ関数がdict
を継承する特徴を持つため、get
関数があるため、自分でマッピングされ、iterableから要素が現れるたびに1増加することがわかります.def _count_elements(mapping, iterable):
mapping_get = mapping.get
for elem in iterable:
mapping[elem] = mapping_get(elem, 0) + 1
most_common1つの関数で、出現回数が最も多い要素から出現回数が最も多いn番目の要素を返します.
nがない場合は、出現回数の降順で並べ替え、nがある場合はheapqを使用します.
self.items()
がheapqに渡されているため、各鍵とその出現回数の値ペアがリストを返すことが予想される.def most_common(self, n=None):
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.items(), key=_itemgetter(1), reverse=True)
# Lazy import to speedup Python startup time
import heapq
return heapq.nlargest(n, self.items(), key=_itemgetter(1))
fromkeysdictの作成時には、
fromkeys
メソッドで鍵リストを簡単に巡回してdictシーケンスを生成することもできます.counterでは、鍵に手動で値を追加することを避ける必要があります.valueはkeyの出現回数に基づいて決定しなければならないからです.例えば、Counter.fromkeys('aaabbc', v=2)
のようにディックシーケンスを生成すると、aが2回現れたという奇妙なデータが表示される.したがって、fromkeys関数が呼び出されると、counterクラスは、以下に示すようにNotImplementedError
に直接発行されます.@classmethod
def fromkeys(cls, iterable, v=None):
raise NotImplementedError(
'Counter.fromkeys() is undefined. Use Counter(iterable) instead.')
Counter使用例文字列sが小文字(「a」から「z」)からなり、使用頻度が最も高い文字を返すソリューション関数を実現します.
ただし、最大2文字以上のアルファベットを使用すると、アルファベット順に文字列が返されます.
def solution(s):
# s= "aabbcdd"
c = Counter(s.lower())
# Counter가 문자열(iterable)로 초기화(__init__)되면서 내부적으로 update를 호출하여 각 letter와 등장횟수를 key,value로 가지고 있는 상태
# Counter({'a': 2, 'b': 2, 'c': 1, 'd': 2})
mc = c.most_common(1)[0][1]
# [('a',2)] 에서 2를 추출
mc_words = [letter for letter, val in c.items() if val == mc]
mc_words.sort()
# 2와 동일한 값을 가지는 value의 key들을 모아서 알파벳 순으로 sort
return ''.join(mc_words)
# abd
Counterのmost_common
関数は、nが与えられたとき、heapq.nlargest(n, self.items(), key=_itemgetter(1))
によってn対の最大値のリストを返す.したがって、[0][1]と同じインデックスを用いてmost_common
から返される値から出場回数を抽出することができる.リファレンス🚩
上記の例を少し修正して、特定のアルファベットの順序を早めたい場合は、どうすればいいですか?
この場合、単純呼
sort()
では所望の結果が得られない.この場合、sort条件をそれぞれ作成するために、各アルファベットの優先度をvalueに設定するdictを作成しました.△もっといい意見があれば、教えてください.😀)
「コードは次のとおりです.」d'優先度の高い例.
def solution(s):
# s= "aabbcdd"
c = Counter(s.lower())
mc_words = [letter for letter, val in c.items() if val == c.most_common(1)[0][1]]
mc_words.sort()
# 여기까지는 동일
words = dict(zip(mc_words, range(len(mc_words))))
# {'a': 0, 'b': 1, 'd': 2}
for word in words.keys():
if word == 'd':
words['d'] = -1
# {'a': 0, 'b': 1, 'd': -1}
answer = ''.join(k for k, v in sorted(words.items(), key=itemgetter(1)))
return answer
# dab
前述したCounterのmost_common
では、最初のインデックスの値に基づいてソートされた次の部分が表示され、いくつかのヒントが得られていることに注意してください.if n is None:
return sorted(self.items(), key=_itemgetter(1), reverse=True)
Reference
この問題について(Python CollectionsモジュールのCounter), 我々は、より多くの情報をここで見つけました https://velog.io/@ninacookie/python-collections모듈의-Counterテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol