0

I have trouble finding a fitting title for this question, so please forgive me.

Many methods in my class look like this:

def one_of_many():
    # code to determine `somethings`
    for something in somethings:
        if self.try_something(something):
            return
    # code to determine `something_else`
    if self.try_something(something_else):
        return
    …

where self.try_something returns True or False.

Is there a way to express this with something like:

def one_of_many():
    # code to determine `somethings`
    for something in somethings:
        self.try_something_and_return(something) # this will return from `one_of_many` on success
    # code to determine `something_else`
    self.try_something_and_return(something_else) # this will return from `one_of_many` on success
    …

I was fiddling with decorators and context managers to make this happen with no success but I still believe that "There must be a better way!".

balast
  • 33
  • 5
  • 1
    You can stuff `if self.try_something(something): return` onto one line just like that, by moving `return` onto the same line, but it doesn't really help readability most of the time. Trying to have a `try_something_and_return` method that returns on behalf of its caller would be even worse. – user2357112 Oct 12 '17 at 20:11
  • @Davit I want it to just return (as in the first code snippet). – balast Oct 12 '17 at 20:14

3 Answers3

1

It looks like itertools to the rescue:

When you say method, I assume this is a method of a class so the code could look like this:

import itertools

class Thing:
    def one_of_many(self):
        # code to determine `somethings`
        for something in itertools.chain(somethings,[something_else]):
            if self.try_something(something):
                return

Hopefully something_else is not too difficult to compute.

quamrana
  • 37,849
  • 12
  • 53
  • 71
1

Hopefully this mcve mimics your problem:

a = [1,2,3]
b = 3
def f(thing):
    print(thing)
    return False

class F:
    pass

self = F()
self.trysomething = f

Map the method to all the things and take action if any return True

if any(map(self.trysomething, a + [b])):
    print('yeay')
else:
    print('nay')

Depending on what a and b actually are you may have to play around with ways to concatenate or flatten/add or chain as @quamrana mentioned.

wwii
  • 23,232
  • 7
  • 37
  • 77
0
if self.try_something(a_thing) or self.try_something(another_thing):
    return

But you'll either need to know your thing's beforehand.. or calculate them with an expression within the function call.

little_birdie
  • 5,600
  • 3
  • 23
  • 28