I am trying to implement a graph representation where each node of the graph has random edges to other nodes but not to itself. Therefore, I am trying to exclude the node itself from the population out of which random.sample
would generate the random neighbors. However, the following code returns "TypeError: Population must be a sequence. For dicts or sets, use sorted(d)."
import random as rnd
gsize=5
graph = [rnd.sample(list(range(gsize)).remove(node), rnd.randint(0, gsize-1)) for node in range(gsize)]
I saw in this question it was suggested to create a variable first and then apply remove()
to it. I tried to refactor it this way
glist = list(range(gsize))
graph = [rnd.sample(glist.remove(node), rnd.randint(0, gsize-1)) for node in range(gsize)]
but now it throws "TypeError: 'NoneType' object is not iterable". I think the problem is essentially the same, i.e. the population is of type NoneType. Is there a neat way of achieving what I need?
list.remove
is an in-place operation and thus returns None
. What you probably want is something like:
graph = [
rnd.sample(
[other for other in range(gsize) if not node == other],
rnd.randint(0, gsize-1)
) for node in range(gsize)
]
Where you are building a non-inclusive set every time.
A more efficient way would be:
from collections import deque
import random as rnd
graph = []
population = deque(range(gsize))
for _ in range(gsize):
# pop the rightmost element
removed = population.pop()
# build the graph with the remaining population
graph.append(rnd.sample(population, rnd.randint(0, gsize-1)))
# add the removed element to the leftmost side
population.appendleft(removed)