Loops with conditions

Question:

So I was about to solve this exercise:
Suppose 1 is friends with 2, and 2 is friends with 3. If 3 is not friends with 1, they will be suggested as a friend.
Create the dictionary of suggestions, grouped by user identifier, and assign it to variable suggestions. The dictionary should be structured as follows:
The key should be the user identifier.
The value should be a list of user identifiers to be suggested as friends, or the empty list if no suggestions exist.

I coded already the friends dictionary with following output:

{1: [11, 17, 18], 2: [3, 8], 3: [2, 4, 8], 4: [3, 14], 5: [7, 10], 6: [], 7: [5, 9, 16], 8: [2, 3, 10], 9: [7], 10: [5, 8, 13, 15, 19], 11: [1, 17, 18], 12: [], 13: [10, 14, 15, 16, 19], 14: [4, 13], 15: [10, 13], 16: [7, 13, 18], 17: [1, 11, 20], 18: [1, 11, 16], 19: [10, 13], 20: [17]}

and then I tried to find the right combination for the loop:

suggestions = {}
for user1 in friends:
    suggestions[user1] = []
    for user2 in friends: 
        for user3 in friends:
            if user1 in friends[user2] and user2 in friends[user3] and user3 not in friends[user1]:
                suggestions[user1].append(user3) 
                
print(suggestions)

unfortunately my output is:

{1: [1, 1, 20, 1, 16], 2: [2, 4, 2, 10], 3: [3, 3, 14, 3, 10], 4: [2, 4, 8, 4, 13], 5: [5, 9, 16, 5, 8, 13, 15, 19], 6: [], 7: [7, 10, 7, 7, 13, 18], 8: [8, 4, 8, 5, 8, 13, 15, 19], 9: [5, 9, 16], 10: [7, 10, 2, 3, 10, 10, 14, 16, 10, 10], 11: [11, 11, 20, 11, 16], 12: [], 13: [5, 8, 13, 4, 13, 13, 7, 13, 18, 13], 14: [3, 14, 10, 14, 15, 16, 19], 15: [5, 8, 15, 19, 14, 15, 16, 19], 16: [5, 9, 16, 10, 14, 15, 16, 19, 1, 11, 16], 17: [17, 18, 17, 18, 17], 18: [17, 18, 17, 18, 7, 13, 18], 19: [5, 8, 15, 19, 14, 15, 16, 19], 20: [1, 11, 20]}
In [19]:

so for person 1: Person one gets a suggestion to be friends with himself??? I don’t know what I am doing wrong – can someone help me on that and additional provide a explanation why he’s doing it a diffrent way than I am doing it?

Thankful for any help!

Best

Asked By: Emma__BB

||

Answers:

This is my solution, I think it is quite readable, but in short: 1) iterate over user and friends of friends_dict, 2) for each friend add (not append) its friends in suggestions_dict[user] if A) the friend is not the user and B) if the friend is not already listed.

Note the use of += instead of .append() in combination with the list comprehension. That simplify the loop quite a bit.

friends_dict = {1: [11, 17, 18], 2: [3, 8], 3: [2, 4, 8], 4: [3, 14], 5: [7, 10], 6: [], 7: [5, 9, 16], 8: [2, 3, 10], 9: [7], 10: [5, 8, 13, 15, 19], 11: [1, 17, 18], 12: [], 13: [10, 14, 15, 16, 19], 14: [4, 13], 15: [10, 13], 16: [7, 13, 18], 17: [1, 11, 20], 18: [1, 11, 16], 19: [10, 13], 20: [17]}
suggestions = {k:[] for k in friends_dict}

for user, friends in friends_dict.items():
    for friend in friends:
        suggestions[user] += [u for u in friends_dict[friend] if (u != user and u not in friends)]

The result is:

{1: [20, 16],
 2: [4, 10],
 3: [14, 10],
 4: [2, 8, 13],
 5: [9, 16, 8, 13, 15, 19],
 6: [],
 7: [10, 13, 18],
 8: [4, 5, 13, 15, 19],
 9: [5, 16],
 10: [7, 2, 3, 14, 16],
 11: [20, 16],
 12: [],
 13: [5, 8, 4, 7, 18],
 14: [3, 10, 15, 16, 19],
 15: [5, 8, 19, 14, 16, 19],
 16: [5, 9, 10, 14, 15, 19, 1, 11],
 17: [18, 18],
 18: [17, 17, 7, 13],
 19: [5, 8, 15, 14, 15, 16],
 20: [1, 11]}
Answered By: alec_djinn

List iterations are helpful here, as is using sets, which easily eliminate duplicates.

It is still a triple loop, for each person in the friends lists we gather all the indices of friends who are not either the person or already the person’s friends.

suggestions = dict()

for k, v in friends.items():
    suggestions[k] = list(set(f for vf in v for f in friends[vf] if f != k and f not in v))

Or, in a single line.

suggestions = dict((k, list(set(f for vf in v for f in friends[vf] if f !=k and f not in v))) for k,v in friends.items())
Answered By: Deepstop
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.