0

so I have a list of objects that I made and every object has the var y. so I want to use the min function to find the lowest y of them without creating a new list of this var or use loops.

from random import randint

class Dot():
    def __init__(self, x=randint(-100, 100), y=randint(-100, 100)):
        self.x, self.y = x, y
d1, d2, d3, d4, d5 = Dot(), Dot(), Dot(), Dot(), Dot()

dots = [d1, d2, d3, d4, d5]

So now I'm trying yo find the lowest y of the dots with the min function without using a list of y for that, I want to use only the list I already created there. I already tried that:

min(dots.y)

but this try is really stupid and I knew it has very low chance to work, so it didn't work of course. I'm using python 3.10 by the way so tell me if I need newer version.

  • 1
    The default arguments only get evaluated once at function definition, so all instances of `Dot` created without explicitely giving an `x` and `y` will use the *same* value as default. You need `def __init__(self, x=None, y=None)` and `if x is None: x = randint(...)`. See for example https://stackoverflow.com/questions/1651154/why-are-default-arguments-evaluated-at-definition-time – Thierry Lathuille Nov 20 '22 at 12:45

1 Answers1

1

Try to use key= parameter of min():

from random import randint


class Dot:
    def __init__(self, x=None, y=None):
        if x is None:
            x = randint(-100, 100)

        if y is None:
            y = randint(-100, 100)

        self.x, self.y = x, y



d1, d2, d3, d4, d5 = Dot(), Dot(), Dot(), Dot(), Dot()

dots = [d1, d2, d3, d4, d5]

print(min(dots, key=lambda d: d.y).y)

Prints (for example):

6

EDIT: The default argument is only get evaluated once, so I've put the random generation into function body. Credits to @Thierry

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • 1
    Note though that d1, d2, d3, d4, d5 all have the same `x` and `y` attributes, because the default arguments only get evaluated once at function definition. – Thierry Lathuille Nov 20 '22 at 12:42
  • @ThierryLathuille Good observation :) I'll put the randint to function body.. – Andrej Kesely Nov 20 '22 at 12:47
  • Alternatively you could say `min(dot.y for dot in dots)` – Peter Wood Nov 20 '22 at 12:59
  • Or instead of defining a lambda you can reuse [**`attrgetter`**](https://docs.python.org/3/library/operator.html#operator.attrgetter) and make what you are doing more explicit: `min(dots, key=attrgetter('y')).y` – Peter Wood Nov 20 '22 at 13:01