列表操作列表

时间:2019-06-03 20:19:01

标签: python list dictionary

我的代码如下:

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} (...)}

Futhermore我想稍微说一下,我的意思是作为键,我想将清单上的每个数字都列出来,例如因为我有5:{6,7},我也想同时拥有6:{5,7}7:{5,6},显然我不应该有任何重复。

我的问题是我该如何实现?

为了使自己更清晰,我想可视化以下图形:

LINK

4 个答案:

答案 0 :(得分:1)

我发现您不太可能希望对每个列表的所有排列进行字典操作,因为您在其中几个中有一个重复的数字,因此可能对所有字典(其中是每个列表),那么您可以这样做:

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}}

答案 1 :(得分:0)

您可以使用dict理解:

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))}

答案 2 :(得分:0)

首先,您不需要构建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将保持不变。

答案 3 :(得分:0)

您可以使用集合中的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}}