Is it possible to have multiple statements in a python lambda expression?

后端 未结 18 1838
感情败类
感情败类 2020-12-12 21:33

I am a python newbie trying to achieve the following:

I have a list of lists:

lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]

相关标签:
18条回答
  • 2020-12-12 22:06

    This is exactly what the bind function in a Monad is used for.

    With the bind function you can combine multiple lambda's into one lambda, each lambda representing a statement.

    0 讨论(0)
  • 2020-12-12 22:07

    Or if you want to avoid lambda and have a generator instead of a list:

    (sorted(col)[1] for col in lst)
    
    0 讨论(0)
  • 2020-12-12 22:08

    Let me present to you a glorious but terrifying hack:

    import types
    
    def _obj():
      return lambda: None
    
    def LET(bindings, body, env=None):
      '''Introduce local bindings.
      ex: LET(('a', 1,
               'b', 2),
              lambda o: [o.a, o.b])
      gives: [1, 2]
    
      Bindings down the chain can depend on
      the ones above them through a lambda.
      ex: LET(('a', 1,
               'b', lambda o: o.a + 1),
              lambda o: o.b)
      gives: 2
      '''
      if len(bindings) == 0:
        return body(env)
    
      env = env or _obj()
      k, v = bindings[:2]
      if isinstance(v, types.FunctionType):
        v = v(env)
    
      setattr(env, k, v)
      return LET(bindings[2:], body, env)
    

    You can now use this LET form as such:

    map(lambda x: LET(('_', x.sort()),
                      lambda _: x[1]),
        lst)
    

    which gives: [345, 465, 333]

    0 讨论(0)
  • 2020-12-12 22:08

    to demonstrate the lambda x:[f1(),f2()] effect which enables us to execute multiple functions in lambda. it also demonstrates the single line if else conditions if you really want to shrink the code.

    • note that f1() can be a lambda function also(recursive lambda or lambda within lambda). and that inner lambda can be a statement/function of your choice.
    • you can also put exec('statement') for example lambda x:[exec('a=[1]'),exec('b=2')]

    a python implementation of touch(linux) command which creates empty files if they are not already existing.

    def touch(fpath):
        check= os.path.exists(fpath)
        (lambda fname1:[open(fname1,"w+",errors="ignore").write(""),print('Touched',fname1)] 
        if not check else None) (fpath)
    

    will print [ Touched fpath ] where fpath is file path given as input. will do nothing if file already exist.

    the (lambda x: [ f(x), f2(x) ] ) (inp) <- we pass the 'inp' as input to lambda which in this case is the fpath.

    0 讨论(0)
  • 2020-12-12 22:09

    You can do it in O(n) time using min and index instead of using sort or heapq.

    First create new list of everything except the min value of the original list:

    new_list = lst[:lst.index(min(lst))] + lst[lst.index(min(lst))+1:]
    

    Then take the min value of the new list:

    second_smallest = min(new_list)
    

    Now all together in a single lambda:

    map(lambda x: min(x[:x.index(min(x))] + x[x.index(min(x))+1:]), lst)
    

    Yes it is really ugly, but it should be algorithmically cheap. Also since some folks in this thread want to see list comprehensions:

    [min(x[:x.index(min(x))] + x[x.index(min(x))+1:]) for x in lst]
    
    0 讨论(0)
  • 2020-12-12 22:09

    I'll give you another solution, Make your lambda invoke a function.

    def multiple_statements(x, y):
        print('hi')
        print('there')
        print(x)
        print(y)
        return 1
    
    junky = lambda x, y: multiple_statements(x, y)
    
    junky('a', 'b');
    
    0 讨论(0)
提交回复
热议问题