-1

I would like to take a list like this: ['5', '0 1', '1 2', '1 8', '2 3'] and return a new list made of tuples like this: [(0,[1]),(1,[0,2,8]),(2[1,3]),(3,[2]),(8,[1])]. The first element of each tuple is an integer and the second element is a list of integers it appears next to in the original list. I cannot use dictionaries, sets, deque, bisect module.

def create_network(file_name):
    friends = open(file_name).read().splitlines()
    network=[]

    for strings in friends:
        relationship=strings.strip().split(' ')
        if len(relationship)==2:
             a,b=relationship
             a=int(a)
             b=int(b)
             if a>=len(network):
                 network.append((a,[b]))
             else:
                 wow=network[a]
                 wow[1].append(b)
                 network[a]=wow


    return network

This is what I have so far. I want it to return: [(0, [1, 2, 3]), (1, [0, 4, 6, 7, 9]), (2, [0, 3, 6, 8, 9]), (3, [0, 2, 8, 9]), (4, [1, 6, 7, 8]), (5, [9]), (6, [1, 2, 4, 8]), (7, [1, 4, 8]), (8, [2, 3, 4, 6, 7]), (9, [1, 2, 3, 5])] but it is returning [(0, [1, 2, 3]), (1, [4, 6, 7, 9]), (2, [3, 6, 8, 9]), (3, [8, 9]), (4, [6, 7, 8]), (5, [9]), (6, [8]), (7, [8])]. I don't know why it isn't working.

Cam
  • 51
  • 1
  • 1
  • 4

2 Answers2

0

You could do something like this:

from itertools import combinations


def create_network(lst):
    seen = {}

    for e in lst:
        for s, t in combinations(map(int, e.split()), 2):
            seen.setdefault(s, set()).add(t)
            seen.setdefault(t, set()).add(s)

    return [(k, sorted(values)) for k, values in seen.items()]


data = ['5', '0 1', '1 2', '1 8', '2 3']
result = create_network(data)

print(result)

Output

[(0, [1]), (1, [0, 2, 8]), (2, [1, 3]), (3, [2]), (8, [1])]

The general idea is to create a dictionary where the keys are the integers and the values are a set of integers it appears next to. The statement map(int, e.split()) creates an iterable of integers, then using combinations pick every possible pair from the iterable, add each pair to the dictionary and finally return the tuples where the values are sorted.

UPDATE (not using any built-in module)

def combinations(m, lst):
    if m == 0:
        return [[]]
    return [[x] + suffix for i, x in enumerate(lst) for suffix in combinations(m - 1, lst[i + 1:])]


def create_network(lst):
    uniques = []
    for s in lst:
        for e in map(int, s.split()):
            if e not in uniques:
                uniques.append(e)

    result = []
    for number in uniques:
        seen = []
        for e in lst:
            values = list(map(int, e.split()))
            for s, t in combinations(2, values):
                if s == number:
                    if t not in seen:
                        seen.append(t)
                elif t == number:
                    if s not in seen:
                        seen.append(s)
        if seen:
            result.append((number, sorted(seen)))

    return sorted(result)


data = ['5', '0 1', '1 2', '1 8', '2 3']
network = create_network(data)
print(network)

Output

[(0, [1]), (1, [0, 2, 8]), (2, [1, 3]), (3, [2]), (8, [1])]

The above code does not use set, dictionary nor any external module. Be warned it can be slow.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
0

You can use a list comprehension:

d = ['5', '0 1', '1 2', '1 8', '2 3']
def find_edges(_d, c):
  return [(a if b == c else b) for a, b in _d if c in [a, b]]

new_d = [[int(c) for c in i.split()] for i in d if len(i) > 1]
_final = []
for i in [h for d in new_d for h in d]:
   if not any(j == i for j, _ in _final):
      _final.append((i, find_edges(new_d, i)))

Output:

[(0, [1]), (1, [0, 2, 8]), (2, [1, 3]), (8, [1]), (3, [2])]
Ajax1234
  • 69,937
  • 8
  • 61
  • 102