Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate list with tuples

I'm just fiddling with a simulation of (Mendel's First Law of Inheritance).

Before i can let the critters mate and analyze the outcome, the population has to be generated, i.e., a list has to be filled with varying numbers of three different types of tuples without unpacking them.

While trying to get familiar with itertools (I'll need combinations later in the mating part), I came up with the following solution:

import itertools

k = 2
m = 3
n = 4

hd = ('A', 'A')       # homozygous dominant
het = ('A', 'a')      # heterozygous 
hr = ('a', 'a')       # homozygous recessive

fhd = itertools.repeat(hd, k)
fhet = itertools.repeat(het, m)
fhr = itertools.repeat(hr, n)

population = [x for x in fhd] + [x for x in fhet] + [x for x in fhr]

which would result in:

[('A', 'A'), ('A', 'A'), ('A', 'a'), ('A', 'a'), ('A', 'a'), ('A', 'a'), ('A', 'a'), ('A', 'a'), ('A', 'a')]

Is there a more reasonable, pythonic or memory saving way to build the final list, e.g. without generating the lists of for the three types of individuals first?

like image 267
Klaus-Dieter Warzecha Avatar asked Jun 14 '13 17:06

Klaus-Dieter Warzecha


1 Answers

You could use itertools.chain to combine the iterators:

population = list(itertools.chain(fhd, fhet, fhr))

Though I would say there's no need to use itertools.repeat when you could simply do [hd] * k. Indeed, I would approach this simulation as follows:

pops = (20, 30, 44)
alleles = (('A', 'A'), ('A', 'a'), ('a', 'a'))

population = [a for n, a in zip(pops, alleles) for _ in range(n)]

or perhaps

allele_freqs = ((20, ('A', 'A')),
                (30, ('A', 'a')),
                (44, ('a', 'a')))

population = [a for n, a in allele_freqs for _ in range(n)]
like image 126
David Robinson Avatar answered Oct 19 '22 05:10

David Robinson