2016-11-22 7 views
1

У меня проблемы со словарями в Python. Я понимаю, что задача очень проста, но я не могу понять. Моя задача - написать функцию, которая преобразует список кортежей в словарь, где ключи словаря представляют людей (из кортежей), а значения представляют их друзей. За ехр:Список кортежей в словарь

pairs_of_people = {("Adam", "Brian"), ("Adam", "Gabe"), ("Adam", "Hagan"), 
    ("Brian", "Calvin"), ("Brian", "Hagan"), 
    ("Calvin", "Dan")}` 

должен вернуться:

{"Adam": {"Brian", "Gabe", "Hagan"}, "Brian": {"Adam", "Hagan", "Calvin"}, "Calvin": {"Brian", "Dan"}} 

Любая помощь? Спасибо. Если кто-то имеет хорошее введение в словари где-то, он был бы весьма признателен. Я просто не могу понять их.

+0

FYI Значения в вашем желаемом выходе являются наборами, а не словарями. Легко спутать эти два, если вы новичок в словарях. –

+0

Благодарим за внимание! :) –

+0

Возможный дубликат [Python construction of value set dictionary] (http://stackoverflow.com/questions/40690537/python-construction-of-value-set-dictionary) –

ответ

2

Очень быстрый способ принудительного использования этого решения - использовать defaultdict. Это добавит к нашему выходному словарю людей и их друзей, если либо «человек», либо «друг» - это необходимый ключ (первый человек во входных кортежах).

from collections import defaultdict 

pairs_of_people = {("Adam", "Brian"), ("Adam", "Gabe"), ("Adam", "Hagan"), 
       ("Brian", "Calvin"), ("Brian", "Hagan"), 
       ("Calvin", "Dan")} 

required_keys = {t[0] for t in pairs_of_people} 

out = defaultdict(set) 

for person, friend in pairs_of_people: 
    if person in required_keys: 
     out[person].add(friend) 
    if friend in required_keys: 
     out[friend].add(person) 

print(out) 
>> {"Adam": {"Brian", "Gabe", "Hagan"}, "Brian": {"Adam", "Hagan", "Calvin"}, 
    "Calvin": {"Brian", "Dan"}} 
+0

Да, это работало и на самом деле немного легче понять, чем первый пример, упомянутый выше. Спасибо. :) –

+0

Еще один вопрос. Как мне сделать точный оборот? Другими словами, как бы преобразовать этот новый словарь обратно в пары людей? –

+0

@ KevinKlarić Реверс на самом деле проще: «дружба = {« Адам »: {« Брайан »,« Гейб »,« Хаган »},« Брайан »: {« Адам »,« Хаган »,« Кальвин »}, «Кальвин»: {«Брайан», «Дэн»}}; li = []; для человека, друзей в дружбе.items(): для друзей в друзьях: li.append ((человек, друг)) ' – DeepSpace

2

Это способ проще построить эту Dict, содержащий sets (видимо) с помощью defaultdict с set как завод по умолчанию:

from collections import defaultdict 

d = defaultdict(set) 

Кроме того, использовать вспомогательный set из names, содержащий первое имя из каждого кортеж. Таким образом, вы можете проверить на членство и, если две пар имен в names наборе они будут добавлены в друге друг в результате наборов:

names = {i[0] for i in pairs_of_people} 

for i, j in pairs_of_people: 
    d[i].add(j) 
    if j in names: 
     d[j].add(i) 

d = dict(d) # if necessarily a dict 

defaultdict является только особым видом Словаря, что делает эти задачи менее утомительный. Теперь d содержит:

print(d) 
{'Brian': {'Hagan', 'Adam', 'Calvin'}, 'Adam': {'Hagan', 'Brian', 'Gabe'}, 'Calvin': {'Brian', 'Dan'}} 

В связи с тем, что ваши кортежи, содержащиеся в наборе, вы не можете иметь заранее заказ, если вы не переместите их в список, а затем отсортировать их. Вы также можете изменить defaultdict, чтобы иметь завод по умолчанию с d = defaultdict(list) и использовать d[i].append(j) и d[j].append(i) вместо .add.

Что касается введения в словари, вы можете перейти в раздел о словарях Python Tutorial.

+0

Это хорошо, но мой результат должен иметь точно такой же порядок, как тот, который я написал выше. –

+1

@ Наборы KevinKlarić не имеют порядка и ни словарей, порядок может отличаться на разных прогонах Python. –

Смежные вопросы