Search code examples
pythonlambdareducefunctools

python reduce return function reference and not the value of the function


Learning Python. I was learning reduce() and was playing with the initialization parameter. The code simply outputs a SHA256 hash of a list of strings. At first I used a for loop to generate the hash. Then, I used functools.reduce() to try and do the same thing.

import functools
import hashlib

def hash_two_strings(a,b):
  c = a + b
  h = hashlib.sha256(c.encode()).hexdigest()
  return h
  
c1 = ['3', 'sha256', 'C=US,O=Entrust', 'CN=review.mysite.com', '1c:08:ea:51', '2/11/2022', '2/11/2023', 'RSA', '2048']

h = hashlib.md5(c1[0].encode()).hexdigest()

for i in range(1, len(c1)):
  s = h+c1[i]
  h = hashlib.sha256(s.encode()).hexdigest()

print (h)

h = functools.reduce(lambda a, b: hash_two_strings, c1[1:], hashlib.sha256(c1[0].encode()).hexdigest())
print (h)

Output: 2b9d651fee9c0ddc75477be6dba8d1d3600551cf2e355e9f4788d3c728d237a3 <function hash_two_strings at 0x000001FF9B6A3E20>

However, reduce() seems to want to return a reference to the function I wrote hash_two_strings(), not the actual hash I was expecting. Any thoughts on how I'm using reduce() incorrectly because I can't see it.


Solution

  • There are two ways to fix your problem:

    h = functools.reduce(hash_two_strings, c1[1:], hashlib.sha256(c1[0].encode()).hexdigest())
    print (h)
    

    Or:

    h = functools.reduce(lambda a, b: hash_two_strings(a, b), c1[1:], hashlib.sha256(c1[0].encode()).hexdigest())
    

    Because lambda as you used it before ignored the a,b arguments and just returned the hash_two_strings function object.

    Remember that if you write function without the parenthesis that is just a function object, not the result of calling the function:

    >>> def round_3_point_5(): return round(3.5)
    ... 
    >>> round_3_point_5
    <function round_3_point_5 at 0x7f04d347b700>
    >>> round_3_point_5()
    4