Списки манипуляций со списком - PullRequest
1 голос
/ 03 июня 2019

Мой код следующий:

import itertools

lists = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]]

names = [item[0] for item in lists]
for x in lists:
    del x[0]

answer = {name:set(L) for name,L in zip(names, lists)}

, что дает мне:

{0: {1}, 1: {2, 8}, 3: {4}, 4: {2}, 2: {5}, 5: {6, 7}, 8: {9, 10, 11, 12}}

Но я хочу добавить ключ к предыдущим элементам для каждой записи. То, что я хочу, это иметь

{0:{1},1:{0,2,8},3:{1,4},4:{3,2} (...)}

Кроме того, я хотел бы немного повернуть его, я имею в виду в качестве ключа, я хочу, чтобы каждый номер, который я имею в списке, например. поскольку у меня есть 5:{6,7}, я также хочу иметь 6:{5,7} и 7:{5,6}, очевидно, у меня не должно быть дубликатов.

У меня вопрос: как мне этого добиться?

Чтобы прояснить ситуацию, я хочу представить следующий график:

LINK

Ответы [ 4 ]

1 голос
/ 04 июня 2019

Я считаю маловероятным, что вы захотите сделать подстановку всех перестановок каждого списка, так как у вас есть дубликаты чисел в нескольких из них, поэтому возможно составление списка всех перестановок (из которых являются перестановками каждый список) тогда вы можете сделать это:

from itertools import permutations

lists = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]]

answer = [{k:set(v) for k, *v in perms} for perms in map(permutations, lists)]

Выход для этого:

[{0: {1}, 1: {0}}, {1: {8, 2}, 2: {8, 1}, 8: {1, 2}}, {3: {4}, 4: {3}}, {4: {2}, 2: {4}}, {2: {5}, 5: {2}}, {5: {6, 7}, 6: {5, 7}, 7: {5, 6}}, {8: {9, 10, 11, 12}, 9: {8, 10, 11, 12}, 10: {8, 9, 11, 12}, 11: {8, 9, 10, 12}, 12: {8, 9, 10, 11}}]

В противном случае, если вы не возражаете потерять некоторые значения для перезаписи, вы можете использовать это понимание

answer = {k:set(v) for perms in map(permutations, lists) for k, *v in perms}

Вывод этого существа:

{0: {1}, 1: {8, 2}, 2: {5}, 8: {9, 10, 11, 12}, 3: {4}, 4: {2}, 5: {6, 7}, 6: {5, 7}, 7: {5, 6}, 9: {8, 10, 11, 12}, 10: {8, 9, 11, 12}, 11: {8, 9, 10, 12}, 12: {8, 9, 10, 11}}
0 голосов
/ 04 июня 2019

Вы можете сделать это с defaultdict из коллекций:

lists = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]]

from collections import defaultdict
edges  = [ (V[0],Vn) for V in lists for Vn in V[1:] ]
result = next( d for d in [defaultdict(set)] if [d[a].add(b) or d[b].add(a) for a,b in edges])
print( dict(result))
# {0: {1}, 1: {0, 8, 2}, 2: {1, 4, 5}, 8: {1, 9, 10, 11, 12}, 3: {4}, 4: {2, 3}, 5: {2, 6, 7}, 6: {5}, 7: {5}, 9: {8}, 10: {8}, 11: {8}, 12: {8}}
0 голосов
/ 03 июня 2019

Прежде всего, вам не нужно составлять список names: деструктурирующее назначение поможет.

>>> lists = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]]
>>> answer = {name:set(L) for name,*L in lists}
>>> answer
{0: {1}, 1: {8, 2}, 3: {4}, 4: {2}, 2: {5}, 5: {6, 7}, 8: {9, 10, 11, 12}}

Теперь вы хотите добавить предыдущий name при вычислении текущего name:list. Вам просто нужно zip список с самим собой, чтобы получить ожидаемый результат:

>>> answer = {name2:set([name1]+L2) for (name1,*L1), (name2,*L2) in zip([[lists[0][1]]]+lists, lists)}
>>> answer
{0: {1}, 1: {0, 8, 2}, 3: {1, 4}, 4: {2, 3}, 2: {4, 5}, 5: {2, 6, 7}, 8: {5, 9, 10, 11, 12}}

Хитрость в том, чтобы добавить элемент до первой версии списка, который не изменит первую name:list. Если вы используете [lists[0][1]], первый name1 является частью первого list2, и set не изменится.

0 голосов
/ 03 июня 2019

Вы можете использовать понимание слова:

lists = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]]
answer = {lists[i][0]: set(([lists[i - 1][0]] if i > 0 else []) + lists[i][1:]) for i in range(len(lists))}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...