Какова базовая реализация для метода Most_common Counter? - PullRequest
0 голосов
/ 16 апреля 2019

Я нашел файл pyi, который имеет следующий def

def most_common(self, n: Optional[int] = ...) -> List[Tuple[_T, int]]: ...

Как это могло произойти? Список не определен, и нет реализации?


Просто выделите несколько ценных предложений для подписчиков:

Список импортируется из модуля набора; это не то же самое, что список. Файл .pyi не нужно импортировать, потому что заглушки никогда не выполняются; они просто должны быть синтаксически верными Python

Если вы используете из будущих импортных аннотаций, вам не придется импортировать набор текста, чтобы использовать List et al. в аннотациях функций в .py файлах, так как аннотации функций будут обрабатываться как строковые литералы. (Начиная с Python 4, это будет поведение по умолчанию. Подробнее см. PEP 563.)

1 Ответ

1 голос
/ 16 апреля 2019

Вы просматриваете файл 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]
...