10

Suppose a = [[1,2,3],[1,2,3]] reduce(lambda x,y: x==y, a) returns True

But if a = [[1,2,3],[1,2,3],[1,2,3]] reduce(lambda x,y: x==y, a) returns False

Why in the second case, the outcome is False?

please help

thanks

Jack
  • 195
  • 2
  • 8
  • If you not insist on `reduce`, there's Q: [Check if all elements in a list are identical](https://stackoverflow.com/questions/3844801/check-if-all-elements-in-a-list-are-identical) – mykhal Jun 26 '21 at 09:59

6 Answers6

11

Try this instead, it works for lists of any size:

all(e == a[0] for e in a)

Notice that your proposed solution using reduce doesn't work for more than two items, as the accumulated value after the first comparison is True, and you'd be comparing True against each of the elements from that point on, and obviously that's not going to work.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
5

You are not reducing the lists. The return value of your lambda is True or False, which is then used as input parameters to further calls to the same lambda function. So you end up comparing a boolean with a list. Therefore, the reducing function should return the same type as it input parameters.

You were probably looking for what other answers proposed instead: use all().

C2H5OH
  • 5,452
  • 2
  • 27
  • 39
4

You can still use reduce! Check out this magic:

bool(reduce(lambda x,y: (x==y)*x, a))

Since the return value of the lambda for x==y is True or False, that can be multiplied by the input and then used in the next comparison because True*[1,2,3] is [1,2,3]. It also works for strings, True*"MyString" is "MyString".

Try it. However, this method will not work for a list of zeros.

divibisan
  • 11,659
  • 11
  • 40
  • 58
billiam
  • 132
  • 1
  • 15
2

Because first time reduce compare [1,2,3] == [1, 2, 3] and it's true next time it compare True and [1,2,3] and it's false.

help(reduce)

Help on built-in function reduce in module __builtin__:

reduce(...)
    reduce(function, sequence[, initial]) -> value

    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).
ddzialak
  • 1,042
  • 7
  • 15
1

a = [range(1, 4), range(1, 4), range(1, 4)]

To evaluate reduce(operator.eq, a) the reduce function will first evaluate the function operator.eq on the first two elements of a to obtain True. Then it will call operator.eq again with True and range(1, 4) as the two arguments, and obtain False which is the final result of reduce.

Perhaps you are wanting:

from functools import partial
import operator
allequal = reduce(partial(operator.eq, a[0]), a[1:])
wberry
  • 18,519
  • 8
  • 53
  • 85
0

Why in the second case, the outcome is False

Because reduce(lambda x, y: x == y, (a, b, c, d)) does not mean (a == b) and (b == c) and (c == d); it means (((a == b) == c) == d). a == b will produce either True or False, which then gets compared to c.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153