0

I would like to avoid pointing to the same object in the below code. Please look at output and desired output stated below.

Code:

import random
prototype = [{'uniqueDict': list()}]

def mapme(somekey):
    global aa
    aa = [random.randint(0, 5), random.randint(6, 10)]
    return dict(zip(aa, len(aa) * prototype))



forSomeKey = ['outer']
FirstSecondOnce = dict(zip(forSomeKey, list(map(mapme, forSomeKey))))

for key in aa:
    location = [['first', 'second']]
    for ixy in location:
        FirstSecondOnce[forSomeKey[0]][key]['uniqueDict'].append(ixy)

print(FirstSecondOnce)

Output:

{'outer': {0: {'uniqueDict': [['first', 'second'], ['first', 'second']]}, 7: {'uniqueDict': [['first', 'second'], ['first', 'second']]}}}

Desired output:

{'outer': {0: {'uniqueDict': [['first', 'second']]}, 7: {'uniqueDict': [['first', 'second']]}}}

Notice that the ['first', 'second'] is appended only once in each key loop iteration, but since they are pointing to same object. I have tried both .copy() and deepcopy(prototype) for prototype, but none has worked. Please suggest how to fix this.

Thank you.

  • `len(aa) * prototype` produces a list with multiple copies of *the same* `{'uniqueDict': list()}`. The empty list here was *already created*; `list` will *not* be called again each time. `list()` means the same (unless `list` is replaced) as `[]`, but is slower. So, once the actual problem is isolated, it is the same as in the linked duplicate. – Karl Knechtel Oct 03 '22 at 19:33
  • 1
    Aside from the aliasing issues, the fact that you're using a global `aa` is bizarre, especially since you then `map` the global-using function over a list. The list happens to only have one element, but if it'll always have only one element, `map` is pointless, and if it'll ever have more, previous values of `aa` will get stomped. – user2357112 Oct 03 '22 at 19:37
  • @KarlKnechtel I know what you mean but I would say not multiple copies of the same object, multiple *references* to the same object – juanpa.arrivillaga Oct 03 '22 at 19:55

1 Answers1

0

Just don't do the prototype thing:

return {x: {'uniqueDict': []} for x in aa}

Trying to deep-copy a template object in Python will usually be slow, error-prone, and awkward, compared to creating a new object the same way you would have created the template.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • 1
    If the goal is to separate out the logic, `prototype` can be implemented as a *function* instead, which `returns` a fresh version `{'uniqueDict': []}` and is *called* where needed. – Karl Knechtel Oct 03 '22 at 19:36