# Roulette wheel

Scott David Daniels Scott.Daniels at Acm.Org
Thu Mar 5 19:06:12 CET 2009

```mattia wrote:
> ... The last question: how can I improve readability in this piece of code?
>
> def crossover(pop, prob=0.6):
>     """
>     With a crossover probability cross over the parents to form new
>     offspring. If no crossover was performed, offspring is the exact copy of parents.
>     """
>     cpop = []
>     for i in range(0, len(pop), 2):
>         # crossover
>         if prob > random():
>             crossover_point = randint(0, len(pop[i])-1)
>             nchromosome1 = pop[i][:crossover_point] + pop[i+1][crossover_point:]
>             nchromosome2 = pop[i+1][:crossover_point] + pop[i][crossover_point:]
>         else:
>             nchromosome1 = pop[i][:]
>             nchromosome2 = pop[i+1][:]
>         cpop += [nchromosome1] + [nchromosome2]
>     return cpop

Python encourages iterating over data, not indices.
Just for fun, I'll do it as a generator:
def crossover(pop, prob=0.6):
'''<keep original comment, say "produces">
note the population is treated pairwise, so any individual
is only likely to cross with one particular other individual.
'''
for first, second in zip(pop[::2], pop[1::2]):
if prob > random():
spot = randint(1, len(first) - 1) # avoid non-crossings
yield first[: spot] + second[spot :]
yield second[: spot] + first[spot :]
else:
# consider not even producing the duplicates
yield first
yield second

def random_crossing(population, probability=0.6):
'''This chooses random pairs from the population.
'''
shuffled = list(population) # make a copy
random.shuffle(shuffled) # mix it up
return list(crossover(shuffled)) # convert back to a list.

--Scott David Daniels
Scott.Daniels at Acm.Org

```