1

I have been trying for a long time now to discover and/or Google myself to an answer on this. In a genetic algorithm I wrote, rand_funcs is to be filled with appropriate randomization functions for genes within a sequence. In this case, it should be filled with two random functions: one generating a random number between 0 and 2 and the other a random number between 0 and 74.

However, as you can see from the following code and the output generated, the result is that both functions generate numbers between 0 and 2. How is this possible? I even tried using deepcopy on max_nr before giving it to the lambda function creator.

Any advice is appreciated!

self.gene_types = ["int74","int2"]
self.sequence_length = len(gene_types)
self.rand_funcs = []
maxnrs = []
for gt in self.gene_types:
    print(gt, file=sys.stderr)
    if gt == "bit":
        self.rand_funcs.append(lambda: random.random() < 0.5)
    elif gt == "float":
        self.rand_funcs.append(random.random)
    elif gt[:3] == "int":
        print("laaaaal", id(gt), gt[3:], file=sys.stderr)
        max_nr = int(gt[3:]) #WHY IS THIS EQUAL TO TWO FOR BOTH AFTER SECOND ITERATION?!?!??!
        maxnrs.append(int(gt[3:]))
        print(maxnrs, max_nr, type(max_nr), id(max_nr), file=sys.stderr)
        print(*map(id, maxnrs), file=sys.stderr)
        if len(self.rand_funcs) >= 1:
            print("meep meep", self.rand_funcs[0](), file=sys.stderr)
            print(*map(id, maxnrs), file=sys.stderr)
        self.rand_funcs.append(lambda: random.randint(0,max_nr))
        print(*map(id, self.rand_funcs), file=sys.stderr)
        for f in self.rand_funcs:
            print("meep", f(), file=sys.stderr)
    else:
        raise ValueError("Unknown gene type")
print(self.rand_funcs[0](), file=sys.stderr)
print(self.rand_funcs[1](), file=sys.stderr)
print("maxes", maxnrs, file=sys.stderr)

This is the output:

int74
laaaaal 140047932053576 74
[74] 74 <class 'int'> 94881069021088
94881069021088
140047869933360
meep 73
int2
laaaaal 140047932053632 2
[74, 2] 2 <class 'int'> 94881069018784
94881069021088 94881069018784
meep meep 2
94881069021088 94881069018784
140047869933360 140047869933496
meep 0
meep 1
2
1
maxes [74, 2]
kakben
  • 119
  • 8
  • `lambda: random.randint(0,max_nr)` is capturing the `max_nr` variable, not its current value. – user2357112 Oct 03 '17 at 22:01
  • Thanks for the quick response. I have also tried `lambda: random.randint(0,gt[3:])` with the same result. Shouldn't this solve the problem if you are correct? – kakben Oct 03 '17 at 22:04
  • That's still capturing the `gt` variable, not the current value of `gt[3:]`. – user2357112 Oct 03 '17 at 22:05
  • This code is kind of a rat's nest and very hard to parse. – Omnifarious Oct 03 '17 at 22:10
  • Ok, I moved the whole thing out to a staticmethod instead and now it works. Thank you for clarifying despite my question being very similar to other questions. – kakben Oct 03 '17 at 22:17

0 Answers0