python-3.x - Counter 的 most_common 方法的底层实现是什么?
问题描述
我找到了一个 pyi 文件,它具有以下定义
def most_common(self, n: Optional[int] = ...) -> List[Tuple[_T, int]]: ...
这怎么可能发生?列表没有定义,没有执行?
在这里为追随者强调一些有价值的建议:
列表是从打字模块导入的;它与列表不同。.pyi 文件不需要导入它,因为存根文件永远不会被执行;它们只需要在语法上是有效的 Python
如果您使用 from future import annotations,您将不必导入类型来使用 List 等。在 .py 文件中的函数注释中也是如此,因为函数注释将被视为字符串文字。(从 Python 4 开始,这将是默认行为。有关详细信息,请参阅 PEP 563。)
解决方案
您正在查看pyi
仅用于注释的文件。它永远不会由 Python 解释器执行。pyi
您可以通过阅读PEP484了解有关文件的更多信息。
使用调试器,在您调用的行上放置一个断点,most_common
然后单步执行该方法。
Python 3.7 实现。
...\Lib\collections\__init__.py
:
def most_common(self, n=None):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter('abcdeabcdabcaba').most_common(3)
[('a', 5), ('b', 4), ('c', 3)]
'''
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.items(), key=_itemgetter(1), reverse=True)
return _heapq.nlargest(n, self.items(), key=_itemgetter(1))
_heapq.nlargest
(in ...\Lib\heapq.py
) 实施:
def nlargest(n, iterable, key=None):
"""Find the n largest elements in a dataset.
Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
"""
# Short-cut for n==1 is to use max()
if n == 1:
it = iter(iterable)
sentinel = object()
if key is None:
result = max(it, default=sentinel)
else:
result = max(it, default=sentinel, key=key)
return [] if result is sentinel else [result]
# When n>=size, it's faster to use sorted()
try:
size = len(iterable)
except (TypeError, AttributeError):
pass
else:
if n >= size:
return sorted(iterable, key=key, reverse=True)[:n]
# When key is none, use simpler decoration
if key is None:
it = iter(iterable)
result = [(elem, i) for i, elem in zip(range(0, -n, -1), it)]
if not result:
return result
heapify(result)
top = result[0][0]
order = -n
_heapreplace = heapreplace
for elem in it:
if top < elem:
_heapreplace(result, (elem, order))
top, _order = result[0]
order -= 1
result.sort(reverse=True)
return [elem for (elem, order) in result]
# General case, slowest method
it = iter(iterable)
result = [(key(elem), i, elem) for i, elem in zip(range(0, -n, -1), it)]
if not result:
return result
heapify(result)
top = result[0][0]
order = -n
_heapreplace = heapreplace
for elem in it:
k = key(elem)
if top < k:
_heapreplace(result, (k, order, elem))
top, _order, _elem = result[0]
order -= 1
result.sort(reverse=True)
return [elem for (k, order, elem) in result]
推荐阅读
- server - 独立运行状况检查
- mysql - 排序 - 按 Laravel 数据库中的喜欢和 ID 排序
- python-3.x - Python 集 - 更新应该被命名为 union_update 吗?
- expo-camera - Expo Camera:“拍照”、“预览”、“重拍选项”和“保存到本地存储”
- css - 使表头相对于某个组件具有粘性
- laravel-backpack - 如何在 Laravel 背包中免费使用 google maps JavaScript Api
- sql - SQL:从数据表中减去某些有限制的行到一个新表中
- tensorflow - Elu int8 量化是否适用于 Tensorflow Lite?
- sql - Azure Synapse Analytics 教程:SQL 语法错误“第 5 行第 1 列解析错误:'WITH' 附近的语法不正确。”
- python - 如何在熊猫中加入列,忽略混合数据类型的零值