[Python] Problemen met referenties in Lambda functie

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • cosmo50
  • Registratie: Mei 2011
  • Laatst online: 02-12-2022
Ik loop tegen iets aan wat, als ik het internet zo zie, vaker een probleem is. Ik probeer voor verschillende datapunten een hele rits aan lambda functies op te bouwen, om dan in een later stadium deze functies te kunnen gebruiken om on-the-fly data te genereren. Een voorbeeld:

Python:
1
2
3
4
5
6
7
8
9
10
11
a = range(0, 3)
names = ['A', 'B', 'C']

example = {}
for idx, name in enumerate(names):
    changing_var = a[idx]
    example[name] = lambda x: x*changing_var

print(example['A'](5))  # Verwacht 0*5 = 0
print(example['B'](5))  # Verwacht 1*5 = 5
print(example['C'](5))  # Verwacht 2*5 = 10


Zoals te zien, wordt er in de lambda functie verwezen naar een getal welke verandert per iteratie. Zoals op stackoverflow te vinden, ligt dit probleem zoals verwacht in de veranderende referentie per iteratie. Echter, met de verschillende opties die daar worden genoemd (hard-coden, volgorde veranderen, verschillende variabele namen, verschillende namespaces gebruiken), verlies ik aardig wat leesbaarheid (denk ik?), en vooral flexibiliteit.

Een aardige omweg lijkt mij om op de een-of-andere manier de variabelen tóch te forceren om gekopieerd te worden, en de reference naar deze nieuwe variabele op te slaan in de lambda. Na verschillende pogingen met deepcopy's e.d., kom ik niet verder.

Denk ik te lastig, en is het toch een betere optie om volledig om het probleem heen te werken? Of zie ik iets over het hoofd?

Beste antwoord (via cosmo50 op 24-05-2022 17:00)


  • luukvr
  • Registratie: Juni 2011
  • Niet online
Waarom zijn de oplossingen in die stackoverflow post niet goed voor jou?

De helper functie oplossing daar lijkt me prima flexibel en leesbaar.

Python:
1
2
3
4
5
6
7
8
9
a = range(0, 3)
names = ['A', 'B', 'C']

def helper_function(name):
    return lambda x: x * a[names.index(name)]

print(helper_function('A')(5))  # Verwacht 0*5 = 0
print(helper_function('B')(5))  # Verwacht 1*5 = 5
print(helper_function('C')(5))  # Verwacht 2*5 = 10

Alle reacties


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • luukvr
  • Registratie: Juni 2011
  • Niet online
Waarom zijn de oplossingen in die stackoverflow post niet goed voor jou?

De helper functie oplossing daar lijkt me prima flexibel en leesbaar.

Python:
1
2
3
4
5
6
7
8
9
a = range(0, 3)
names = ['A', 'B', 'C']

def helper_function(name):
    return lambda x: x * a[names.index(name)]

print(helper_function('A')(5))  # Verwacht 0*5 = 0
print(helper_function('B')(5))  # Verwacht 1*5 = 5
print(helper_function('C')(5))  # Verwacht 2*5 = 10

Acties:
  • 0 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 12:38
Of gewoon een enkele lambda zoals dit?
code:
1
2
3
4
5
6
names = ['A', 'B', 'C']
example = lambda x,y: x*y

print (example(names.index('A'), 5))
print (example(names.index('B'), 5))
print (example(names.index('C'), 5))

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


Acties:
  • 0 Henk 'm!

  • cosmo50
  • Registratie: Mei 2011
  • Laatst online: 02-12-2022
Ja, die helper lijkt inderdaad toch het voor elkaar te krijgen. Denk dat ik het initieel verkeerd interpreteerde. Dank!