Функция python Возвращает словарь, содержащий значения вместе с соответствующим списком ключей, которые имели это значение из исходного словаря. - PullRequest
0 голосов
/ 29 октября 2018

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

>>> rating = {"bob": "excellent", "barnum": "passing", "beatrice": "satisfactory", "bernice": "passing", "ben": "no pass", "belle": "excellent", "bill": "passing", "bernie": "passing", "baxter": "excellent"}
>>> new_dict(rating) # new_dict is the function
>>> {'excellent': ['bob', 'belle', 'baxter'], 'passing': ['barnum', 'bernice', 'bill', 'bernie'], 'satisfactory': ['beatrice'], 'no pass': ['ben']}

Ответы [ 3 ]

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

Я не вижу хорошего способа написать это как понимание. Рассмотрим defaultdict из модуля collections.

>>> from collections import defaultdict
>>> 
>>> result = defaultdict(list)
>>> for k, v in rating.items():
...:    result[v].append(k)
...:    
>>> result
>>> 
defaultdict(list,
            {'excellent': ['bob', 'baxter', 'belle'],
             'no pass': ['ben'],
             'passing': ['barnum', 'bernice', 'bill', 'bernie'],
             'satisfactory': ['beatrice']})

Это имеет временную сложность O (n), любое понимание, которое я пробовал, например

>>> {v:[k for k, v_ in rating.items() if v_ == v] for v in rating.values()}
>>> 
{'excellent': ['bob', 'baxter', 'belle'],
 'no pass': ['ben'],
 'passing': ['barnum', 'bernice', 'bill', 'bernie'],
 'satisfactory': ['beatrice']}

намного хуже при O (n ** 2).

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

Использовал понимание списка, чтобы максимально сократить ответ. Я уверен, что есть способ свести функцию к одной строке.

def new_dict(rating):
    my_dict = dict([(i,[]) for i in set([value for key,value in rating.items()])])
    [my_dict[value].append(key) for key,value in rating.items()]
    return my_dict

rating = {"bob": "excellent", "barnum": "passing", "beatrice": "satisfactory", "bernice": "passing", "ben": "no pass", "belle": "excellent", "bill": "passing", "bernie": "passing", "baxter": "excellent"}
print(new_dict(rating)) # new_dict is the function

Это печатает вывод:

{'excellent': ['bob', 'belle', 'baxter'], 'passing': ['barnum', 'bernice', 'bill', 'bernie'], 'satisfactory': ['beatrice'], 'no pass': ['ben']}
0 голосов
/ 29 октября 2018

Вы можете использовать itertools.groupby и сортировку, чтобы сделать одну строку:

>>> from itertools import groupby
>>> {k:[x[0] for x in g] for k,g in groupby(sorted(rating.items(), key=lambda x:x[1]),lambda x:x[1])}
{'passing': ['bernice', 'barnum', 'bernie', 'bill'], 'no pass': ['ben'], 'excellent': ['belle', 'baxter', 'bob'], 'satisfactory': ['beatrice']}
>>>

но это неоправданно неэффективно, оно требует операции сортировки, которая материализует вспомогательный список, и это слишком сложно. Не стремитесь писать однострочники. Написать чистый читаемый код, который эффективно использует структуры данных Python. Просто используйте collections.defaultdict для этого, это канонический способ группировки вещей:

>>> from collections import defaultdict
>>> grouper = defaultdict(list)
>>> for k,v in rating.items():
...     grouper[v].append(k)
...
>>> grouper
defaultdict(<class 'list'>, {'passing': ['bernice', 'barnum', 'bernie', 'bill'], 'excellent': ['belle', 'baxter', 'bob'], 'satisfactory': ['beatrice'], 'no pass': ['ben']})
>>>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...