Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

422
Visualizações
Iteration in a for loop overwrites previously defined distinct dict keys when linking new keys to new lambda functions. Is this expected?

I am possibly very naive, but I find the following behaviour unexpected.

Introduction: I need a wrapper to address dynamically the methods of my own class, model. I am trying to use a dict to have a separate entry for each of a given number of members of the class that are dynamically requested. I link the dict keys to the chosen members iteratively and I find that the doc string is preserved, but the methods get overwritten by the last item in the iteration, despite their distinct keys. Here is a snippet where I reproduce the behaviour with numpy, in place of my own class.

import numpy as np
name = ["sin","cos"]

bnd = {}
print('Within the defining loop, it works!\n')
for nam in name:
    # useless indirect function (with doc string)
    # equivalent to sin(2*pi*x) 
    # or to cos(2*pi*x)
    bnd[nam] = lambda x, par: np.__getattribute__(nam)(x*par)
    bnd[nam].__doc__ = '"""'+nam+'"""'
    print('bnd doc in-loop: {} = {}'.format(nam,bnd[nam].__doc__))
    print('bnd method in-loop {}(0,2*pi) = {}'.format(nam,bnd[nam](0,2*np.pi)))

print('\n    However after the loop...')
print('bnd keys {}'.format(bnd.keys()))
print('\nfirst function doc: {}'.format(bnd["sin"].__doc__))
print('doc is preserved, but instead the method')
print('(should be sin(2 pi *0)) yields {}'.format(bnd["sin"](0,2*np.pi)))
print('\nsecond trial_function doc: {}'.format(bnd["cos"].__doc__))
print('doc is preserved, again, and this time the method')
print('(should be cos(2 pi *0)) yields  correctly {}'.format(bnd["cos"](0,2*np.pi)))
print('\nSummary: bnd[nam] gets overwritten by the last lambda definition in the loop. \n\nWhy????') 

If you run the code you get the following

Within the defining loop, it works!

bnd doc in-loop: sin = """sin"""
bnd method in-loop sin(0,2*pi) = 0.0
bnd doc in-loop: cos = """cos"""
bnd method in-loop cos(0,2*pi) = 1.0

    However after the loop...
bnd keys dict_keys(['sin', 'cos'])

first function doc: """sin"""
doc is preserved, but instead the method
(should be sin(2 pi *0)) yields 1.0

second trial_function doc: """cos"""
doc is preserved, again, and this time the method
(should be cos(2 pi *0)) yields  correctly 1.0

Summary: bnd[nam] gets overwritten by the last lambda definition in the loop. 

Why????

which I hope is clarifying my question.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

As others have explained. There is only one variable nam in your function. When you create the lambda, it doesn't capture the value of nam as it was when created the lambda. Rather all the lambdas share the same nam, and it has whatever value it had at the end of the function.

There are several get arounds. Essentially you need to capture nam as a variable.

The "official" way to do this is that you could just write:

   def attribute_getter(nam):
      return lambda x, par: np.__getattribute__(nam)(x*par)
   bind[nam] = attribute_getter(nam)

The quick and dirty solution is:

   bind[nam] = lambda x, par, nam=nam: np.__getattribute__(name)(x * par)

The variable nam is turned into an optional which is set to the current value of nam.


Edit: Changed "program" to "function".

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda