2016-11-16 2 views
2

Вход:Группировка строк из набора в словарь питона

>>> foo = {("A", "B"), ("A", "G"), ("A", "H"), 
...   ("B", "C"), ("B", "H"), 
...   ("C", "D"), 
...   ("D", "E"), ("D", "G"), ("D", "H"), 
...   ("E", "F"), ("E", "G"), ("E", "H"), 
...   ("F", "I"), ("F", "J"), ("F", "K"), 
...   ("G", "H")} 

Я пытаюсь группировать свой сет, как это, я до сих пор не увенчались успехом, мне удалось сгруппировать их только как это.

Фактический выход:

>>> {k:set(x[1] for x in v) for k,v in itertools.groupby(sorted(foo), key=lambda x: x[0])} 
{'B': {'C', 'H'}, 'E': {'H', 'G', 'F'}, 'D': {'E', 'G', 'H'}, 'A': {'B', 'G', 'H'}, 'C': {'D'}, 'G': {'H'}, 'F': {'I', 'K', 'J'}} 

Однако, это мой желаемый результат:

foo1 = {"A": {"B", "G", "H"}, 
     "B": {"A", "H", "C"}, 
     "C": {"B", "D"}, 
     "D": {"C", "E", "G", "H"}, 
     "E": {"D", "F", "G", "H"}, 
     "F": {"E", "I", "J", "K"}, 
     "G": {"A", "D", "E", "H"}, 
     "H": {"A", "B", "D", "E", "G"}, 
     "I": {"F"}, 
     "J": {"F"}, 
     "K": {"F"} 
     } 

Я думал, с перестановками или комбинациями? Но я до сих пор не знаю, как это сделать. Спасибо заранее. Редактировать: Добавлено изображение того, как связаны строки.

+0

Что вы хотите, чтобы определить, как ул группируются? EDIT: подождите, я думаю, что вижу это, но, пожалуйста, поставьте это в вопросе. –

+0

Учитывая, что набор Python и dict по существу неупорядочен, ожидаете ли вы определенный порядок для своего вывода? – Guillaume

+0

Ваша сортировка по понятным пониманию действительно сортируется должным образом, но она не печатает ее вам так, как вы хотите? Edit: nvm, я вижу некоторые ошибки в том, что вы получили –

ответ

2

OP просил, чтобы это было сделано с пониманием, так вот безвозмездное один лайнер:

(Пожалуйста, пожалуйста, пожалуйста, не делайте это так)

python3 
Python 3.5.2+ (default, Sep 22 2016, 12:18:14) 
[GCC 6.2.0 20160927] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import itertools 
>>> import pprint 
>>> 
>>> foo = {("A", "B"), ("A", "G"), ("A", "H"), 
...   ("B", "C"), ("B", "H"), 
...   ("C", "D"), 
...   ("D", "E"), ("D", "G"), ("D", "H"), 
...   ("E", "F"), ("E", "G"), ("E", "H"), 
...   ("F", "I"), ("F", "J"), ("F", "K"), 
...   ("G", "H")} 
>>> 
>>> foo1 = {k: {x[1] for x in v} for k, v in itertools.groupby(sorted(foo | {(a, b) for b, a in foo}), key=lambda x: x[0])} 
>>> pprint.pprint(foo1) 
{'A': {'H', 'B', 'G'}, 
'B': {'C', 'H', 'A'}, 
'C': {'D', 'B'}, 
'D': {'C', 'E', 'H', 'G'}, 
'E': {'D', 'H', 'F', 'G'}, 
'F': {'K', 'J', 'E', 'I'}, 
'G': {'D', 'E', 'H', 'A'}, 
'H': {'D', 'E', 'B', 'G', 'A'}, 
'I': {'F'}, 
'J': {'F'}, 
'K': {'F'}} 
+0

'{(k, v) для k в foo1 для v в foo1 [k]}' –

+0

@ PatrickHaugh: Что это за замена? Что бы это ни заменило, было бы неплохо сделать это как «{(k, v) для k, vs в foo1.items() для v в vs}'; сохраняет избыточный поиск для каждого ключа, но я не уверен, в чем его цель. – ShadowRanger

+0

@ShadowRanger OP попросил убрать исходный список из словаря, но затем удалил свой комментарий. –

-1

Вы можете использовать обычный словарь, но defaultdict делает это немного проще.

from collections import defaultdict 

d=defaultdict(set) 
for key, value in foo: 
    f[key].add(value) 

При регулярном Dict:

d = {} 
for key, value in foo: 
    if key not in d: 
     d[key]=set() 
    d[key].add(value) 
+0

Для записи, в то время как она тратит время на создание пустых множеств и их отбрасывание, вы можете упростить регулярный файл dict из трех запросов 'dict' до одного, удалив тестирование членства и просто сделав:' для ключа, значение в foo: ' , 'foo1.setdefault (key, set()). add (value)', 'foo1.setdefault (value, set()). add (key)'. Или, чтобы избежать накладных вызовов 'set', в Py 3.5 и выше, используйте одноглазого оператора обезьяны (названного мной мной), чтобы сделать пустой набор с помощью синтаксиса вместо вызовов конструктора:' foo1.setdefault (key, { *()}). добавить (значение) '.:-) – ShadowRanger

4

Что-то вроде этого?

foo = {("A", "B"), ("A", "G"), ("A", "H"), ("B", "C"), ("B", "H"), ("C", "D"), ("D", "E"), ("D", "G"), ("D", "H"), ("E", "F"), ("E", "G"), ("E", "H"), ("F", "I"), ("F", "J"), ("F", "K"), ("G", "H")} 

from collections import defaultdict 

result = defaultdict(set) 

for key1, key2 in foo: 
    result[key1].add(key2) 
    result[key2].add(key1) 

from pprint import pprint 
pprint(result) 

Который, в отличие от других ответов до сих пор, дает желаемый результат, хотя и неупорядоченное:

{'A': {'B', 'G', 'H'}, 
'B': {'A', 'C', 'H'}, 
'C': {'B', 'D'}, 
'D': {'G', 'C', 'H', 'E'}, 
'E': {'G', 'D', 'H', 'F'}, 
'F': {'I', 'J', 'K', 'E'}, 
'G': {'A', 'D', 'H', 'E'}, 
'H': {'B', 'A', 'G', 'D', 'E'}, 
'I': {'F'}, 
'J': {'F'}, 
'K': {'F'}} 
+0

@HappyUnicorn вы можете сделать это с пониманием: https://stackoverflow.com/a/40639178/833093 –

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