Search code examples
pythonpython-3.xpython-2.xxor

__xor__ in functools.reduce() causing error


I'm currently working in python 3 with the Discord API and I want to use a module that was written in python 2. I'm editing some of the code for it to work with python 3. Something I can't figure out is this:

odd_xor = reduce(__xor__, bh) >> 16

This works in python 2 but doesn't in python 3. The simple fix that I thought would work was:

odd_xor = functools.reduce(__xor__, bh) >> 16

but this gives me the error:

reduce() of empty sequence with no initial value

bh is initialized here:

# bh stands for binary hand, map to that representation
card_to_binary = HandEvaluator.Six.card_to_binary_lookup
bh = map(card_to_binary, hand)

I don't really understand what the code segment is trying to do which is why it is so difficult for me to find a solution to this problem. Any thoughts? Thanks in advance!

P.S. if there is an easier way to use python 2 modules with python 3 projects, please enlighten me.


Solution

  • In Python 3, map returns a lazy iterator (much like a generator), rather than a list the way it did in Python 2. This may be the cause of your issue.

    In your code, you do map(card_to_binary, hand). If hand gets changed (e.g. emptied) before you use the result, you may not get what you want (e.g. the map may end up iterating over nothing).

    To make the code work the same as Python 2, you can simply call list on the iterator you get from map:

    bh = list(map(card_to_binary, hand))
    

    Alternatively, you could change other code that modifies hand so that it does something different, perhaps making a new list, copying the list before modifying it, or only modifying hand in place after the reduce call has been completed.