Счетчик сортировки потерян при объединении с defaultdict - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь взять список из (item_number, fruit) кортежей и посчитать, сколько раз каждый вид фруктов появляется в списке.Это достаточно просто с collections.Counter.Я использую most_common() вместе с этим.

Проблема, с которой я сталкиваюсь, состоит в том, чтобы попытаться также показать список номеров элементов, которые соответствуют определенному типу фруктов, которые они вышли из строя.

Вот мой пример кода:

#!/usr/bin/env python

from collections import Counter, defaultdict

mylist = [
            (1, 'peach'),
            (2, 'apple'),
            (3, 'orange'),
            (4, 'apple'),
            (5, 'banana'),
            (6, 'apple'),
            (7, 'orange'),
            (8, 'peach'),
            (9, 'apple'),
            (10, 'orange'),
            (11, 'plum'),
            ]

# FIRST, HANDLE JUST COUNTING THE ITEMS

normal_list = []

# append to a simple list
for item_number, fruit in mylist:
    normal_list.append(fruit)

# prints just the name of each fruit and how many times it appears
for fruit, count in Counter(normal_list).most_common(10):
    print(f'{fruit}\tCount: {count}')  

# NOW TRY TO INCLUDE THE LIST IF ITEM NUMBERS ALSO

mydefaultdict = defaultdict(list)

# append to the defaultdict
for item_number, fruit in mylist:
    mydefaultdict[fruit].append(item_number)

# prints each fruit, followed by count, and finally the list of IPs for each
for fruit, item_list in Counter(mydefaultdict).most_common(10):
    print(f'{fruit}\tCount: {len(item_list)}\tList: {item_list}')

Я получаю ожидаемый результат для более простой версии:

apple   Count: 4
orange  Count: 3
peach   Count: 2
banana  Count: 1
plum    Count: 1

Однако, когда я пытаюсь добавить список item_numberк этому, результаты больше не сортируются, что приводит к хаосу, когда я использую значение most_common() меньше, чем общее количество сортов фруктов:

plum    Count: 1    List: [11]
banana  Count: 1    List: [5]
orange  Count: 3    List: [3, 7, 10]
apple   Count: 4    List: [2, 4, 6, 9]
peach   Count: 2    List: [1, 8]

Я уверен, что я мог бы сделать что-то по-другомуздесь, но я не совсем уверен, что.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Эта часть сложна:

Counter(mydefaultdict)

Ваш объект mydefaultdict уже заполнен списками в качестве значений, но объекты Counter обычно имеют положительные целые числа в качестве значений.На самом деле это не ошибка, поскольку Counter является подклассом dict, поэтому он будет принимать любой dict в качестве аргумента инициализатора.За исключением того, что есть проблема: most_common больше не возвращает здравомыслящие результаты (если вам было любопытно, он фактически размещает лексикографический порядок на основе списков).

Возможно, более понятным будет что-токак это:

most_common_fruits = sorted(mydefaultdict, key=lambda f: len(mydefaultdict[f]), reverse=True)
for fruit in most_common_fruits:
    item_list = mydefaultdict[fruit]
    ...

Теперь вывод выглядит так:

apple   Count: 4    List: [2, 4, 6, 9]
orange  Count: 3    List: [3, 7, 10]
peach   Count: 2    List: [1, 8]
banana  Count: 1    List: [5]
plum    Count: 1    List: [11]
0 голосов
/ 24 октября 2018

Counter(mydefaultdict) не делает то, что вы думаете делает.Вы подаете defaultdict из списков в Counter, целью которых является подсчет вхождений , а не вычисление длин списков.Действительно, значения вашего Counter объекта - это просто списки, а не целые числа.Counter не жалуется, потому что это подкласс dict и, например, dict можно инициализировать с другим словарем.

Для заказа на самый длинный список вы можете использовать heapq.nlargest с пользовательской функцией:

from heapq import nlargest

for fruit, item_list in nlargest(10, mydefaultdict.items(), key=lambda x: len(x[1])):
    print(f'{fruit}\tCount: {len(item_list)}\tList: {item_list}')

apple   Count: 4    List: [2, 4, 6, 9]
orange  Count: 3    List: [3, 7, 10]
peach   Count: 2    List: [1, 8]
banana  Count: 1    List: [5]
plum    Count: 1    List: [11]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...