24

For usual functions, you can annotate the type as follows

def my_function(arg1: int)

How do I do this in lambda?

lambda a: int, b: int : a+b

gives a syntax error.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Rufus
  • 5,111
  • 4
  • 28
  • 45
  • If Python tells you that `'int' object is not subscriptable`, it means that you are asking it to call `[]` on an `int`. Telling that these objects are lists will not change anything, since they still are actual integers. Besides, specifying the type of arguments in Python is, I believe, nothing more than a tool to produce self-documented code. The Python interpreter, as far as I know, is not expected to have some particular behaviour when coming across an object whose type has been declared. – Right leg Dec 06 '16 at 07:34
  • Type annotations don't fix TypeErrors. – jonrsharpe Dec 06 '16 at 08:01
  • 1
    @jonrsharpe Man that was a harsh edit – Right leg Dec 06 '16 at 08:15
  • 1
    @Rightleg there were two completely different questions; as there were answers to both, I picked the one that didn't seem to be a dupe of other *"how do I reduce"* questions. – jonrsharpe Dec 06 '16 at 08:18
  • 1
    @jonrsharpe Gonna have to delete all the answers related to that part, then – Right leg Dec 06 '16 at 08:19
  • Apologies for the poorly asked question – Rufus Dec 06 '16 at 09:43

3 Answers3

36

The question was: "How to specify argument type in python lambda?". Although the other answers are good, they do not provide answer to this main question.

The answer is: you cannot.

From the PEP specification of function annotations:

lambda 's syntax does not support annotations. The syntax of lambda could be changed to support annotations, by requiring parentheses around the parameter list. However it was decided [12] not to make this change because:

It would be an incompatible change. Lambda's are neutered anyway. The lambda can always be changed to a function.

For reference: https://stackoverflow.com/a/33833896/7051394

Community
  • 1
  • 1
Right leg
  • 16,080
  • 7
  • 48
  • 81
1

For your particular problem, let's see how reduce works:

lambda a, b : a[0] + b[0]

Here, a is the result of previous iteration and b is the current element.

Now, let's see your program:

functools.reduce(lambda a, b : a[0] + b[0], [[0,1], [2,3]])

Details:

iter #1: a = [0,1], b = [2,3], so, a[0] + b[0] = 0 + 2 =3 

It works.

But when you do:

functools.reduce(lambda a, b : a[0] + b[0], [[0,1], [2,3], [4,5]]) 

Details:

iter #1: a = [0,1], b = [2,3], so, a[0] + b[0] = 0 + 2 =3 
iter #2: a = 3, b = [4,5], so, a[0] + b[0] = Error, as you can't subscript an integer `3` (3[0] > Error). 

Error regeneration:

>>> a = 1
>>> a[0]

Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not subscriptable


You can get the desired result with:

a = [[0,1], [2,3], [4,5]]
print sum(map(lambda x:x[0],a))

Or,

print sum(i[0] for i in a)
Ahsanul Haque
  • 10,676
  • 4
  • 41
  • 57
1

The problem is that reduce will compute

result1 = func(x1, x2)
result2 = func(result1, x3)
...

your function accepts two lists and returns a number, so on the second call the function fails (unless you only provide two elements).

To be able to use reduce the function should accept two arguments and return a value of the same type of the arguments because the output of the function will be re-used as input at next iteration.

6502
  • 112,025
  • 15
  • 165
  • 265