1

I'm python newbie and I'am currently struggling with one problem. I have a list of lists:

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

My aim is to make a dictionary from it with the following format:

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

In short:

It has to make a dictionary with unique keys from 1 to 12 in this case (all unique numbers in a list), and to each key it assigns a list of values, which is a common subset for this key i.e for key 2 it appears in lists [4,2], [2,5], [1,2,8] so it has to assign to a key 2 a value which is a list of numbers in those 3 lists except 2.

Thus the output for key 2 should be: 2:[8,1,4,5] etc.

I've made some code:

data = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]] graph = {} for i in range(13): graph[i] = 3 numbers = list(range(0,13)) for row in data: for i in graph.keys(): if i in row: graph[i] = row for key,value in graph.items(): graph[key] = graph[key][1:] print(graph) 

Yet, it gives me output:

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

I really don't know how to combine those lists from this in such a way that I will get desired output.

1
  • 2
    Why 2: [8,1,4,5]? sublists appear [1,2,8], [3,4], [4,2], [2,5], so it should be 2: [1, 8, 4, 5]. Also why 1: [2, 8] and not 1: [0, 2, 8]? Commented May 31, 2019 at 20:24

5 Answers 5

2
d=dict() entries=[] for i in range(0,13): entries=[] for j in data: if i in j: entries+=[num for num in j if num!=i] d[i]=entries 

Output

{0: [1], 1: [0, 2, 8], 2: [1, 8, 4, 5], 3: [4], 4: [3, 2], 5: [2, 6, 7], 6: [5, 7], 7: [5, 6], 8: [1, 2, 9, 10, 11, 12], 9: [8, 10, 11, 12], 10: [8, 9, 11, 12], 11: [8, 9, 10, 12], 12: [8, 9, 10, 11]} 
Sign up to request clarification or add additional context in comments.

Comments

2

You're assigning graph[i] to only one row, so if you come across another row containing i, the answers from your initial row will get reassigned. Instead you might want to assign an empty list to graph[i] instead of 3 append to graph[i] instead.

graph = {} for i in range(13): graph[i] = [] for row in data: for i in graph.keys(): if i in row: for val in row: if val != i: graph[i].append(val) 

Comments

2

You could use a defaultdict here:

from collections import defaultdict mylist = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]] d = defaultdict(list) # a dictionary with all values defaulting to lists for lst in mylist: for val in lst: # extend each list with new values provided they aren't # equal to the key in question d[val].extend([x for x in lst if x!=val]) d # {0: [1], 1: [0, 2, 8], 2: [1, 8, 4, 5], 8: [1, 2, 9, 10, 11, 12], 3: [4], 4: [3, 2], 5: [2, 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]} 

By using a defaultdict, you don't have to worry about assigning a list to the value by default, so you can just use the standard list attributes like append and extend.

There is a performance consideration, as you iterate over lst N+1 times, where N is the length of lst. extend is an O(N) operation, so building the list and extending the existing one isn't exactly performant. It also won't account for duplicate values (if that matters to you). However, it's a bit cleaner than trying to use a standard dict, which you could do:

d = {} for lst in mylist: for val in lst: if val not in d: d[val] = [x for x in lst if x!=val] else: d[val].extend([x for x in lst if x!=val]) d # {0: [1], 1: [0, 2, 8], 2: [1, 8, 4, 5], 8: [1, 2, 9, 10, 11, 12], 3: [4], 4: [3, 2], 5: [2, 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]} 

Where you have to check if val is in the dictionary to build the list, otherwise, you can modify the value in-place with extend

Comments

1

Are you looking to fix your code specifically or are you just looking for a solution?

data = [[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]] n = 12 # Create dict with empty list for each key result = {key: [] for key in range(n + 1)} for key in result: for x in data: if key in x: # We need to make a copy of `x` because otherwise we'd modify `data` x = x.copy() x.remove(key) result[key].extend(x) print(result) 

It's an approach with emphasis on clarity so I'm sure runtime could still be improved. It prints:

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

Also, does the order matter?

Comments

1
a=[[0,1], [1,2,8], [3,4], [4,2], [2,5], [5,6,7], [8,9,10,11,12]] from collections import defaultdict dic=defaultdict(list) for i,v in enumerate(a): for j, v2 in enumerate(v): new_s=a[i][:j]+a[i][j+1:] dic[v2].extend(new_s) for i in dic: dic[i]=list(set(dic[i])) print(dict(dic)) 

output

{0: [1], 1: [0, 8, 2], 2: [8, 1, 4, 5], 8: [1, 2, 9, 10, 11, 12], 3: [4], 4: [2, 3], 5: [2, 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] } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.