0

I was wondering if there was a simple alternative to lambda in my code.

def add_attack(self, attack_name):
        if attack_name in self.known_attacks and attack_name not in self.attacks:
            try:
                assert(len(self.attacks) < 4)
                self.attacks[attack_name] = self.known_attacks.get(attack_name)
                return True
            except:
                #find the min value of self.attacks
                minval = min(self.attacks.keys(), key=(lambda k: self.attacks[k]))
                for keys, values in self.attacks.items():
                    if self.attacks[minval] == values and min(minval, keys) == keys:
                        minval = keys
                del self.attacks[minval]
                self.attacks[attack_name] = self.known_attacks.get(attack_name)
                return True
        else:
            return False

I'm still learning python, and the lambda function is throwing me off since I haven't learned that much about it yet. Instead of using lambda, can someone help me out with another function to replace lambda? Thanks!

  • The lambda expression is not really that intimidating if you think about what it does: it takes whatever arguments are given to it (usually you will find this argument list in the documentation to the function you are passing the lambda to); it evaluates whatever expression is inside it, and returns that value. In this case, the argument list is the keys of `self.attacks`, and the value returned as the "key" is that key's value in `self.attacks`. The `min` function uses the key to decide which one is the smallest. What about the lambda are you confused by? – Pranav Hosangadi Nov 28 '22 at 07:03
  • Note that [bare exceptions are frowned upon](https://stackoverflow.com/questions/30294977/any-reason-why-bare-excepts-are-frowned-upon). In this case better to have: `except AssertionError:`. – DarrylG Nov 28 '22 at 07:36

2 Answers2

3

You could define a function for it:

def return_attacks(self,k):
    return self.attacks[k]

And use that function in the key:

minval = min(self.attacks.keys(), key=(self.return_attacks))

I would strongly recommend you get comfortable with lambda functions - and I think it is clear to you now that lambda x : expr(x) is equivalent to func when

def func(x):
    return expr(x)
  • 1
    Your "return_attacks" function is basically `self.attacks.get`. You could just use that as the key (although the behavior when the key `k` doesn't exist would be different (although not relevant in this use-case). – Pranav Hosangadi Nov 28 '22 at 07:11
1

A lambda should not scare you! It's just a small anonymous function.

It can take any number of arguments, but can only have one expression.

minval = min(self.attacks.keys(), key=(lambda k: self.attacks[k]))

Here you are getting the result of the expression min() as minval

The min function can take keys, here is more about that. I can see it can be confusing, but this key is not the same thing with a dictionary key. This key is just a way to tell the min function how it should behave.

If we go back to the code:

So the line basically finds the minimum value in self.attacks.keys(), with a lambda function that returns every element in self.attacks[]

If you do not want to use lambda, you can write a function in your class that does exactly the same thing.

def find_min_key(self, my_dict):
    return min(my_dict, key= my_dict.get)

You can use this as:

min_val = self.find_min_key(self.attacks)