Home > OS >  Strange behavior using & in if statement in Python
Strange behavior using & in if statement in Python

Time:06-29

While solving one of the problems, I found a strange behavior.

def sortedSquares(nums: list[int]) -> list[int]:   
    pointer = len(nums) - 1
    
    for i in range(pointer):
        if nums[pointer] > abs(nums[0]) & nums[pointer-1] < abs(nums[0]):
            nums.insert(pointer, abs(nums[0]))
            nums.remove(nums[0])
            pointer -= 1
        elif nums[pointer] < abs(nums[0]):
            nums.insert(pointer 1, abs(nums[0]))
            nums.remove(nums[0])
            pointer -= 1
        else:
            pointer -= 1

    return [num ** 2 for num in nums]

It's working fine for the following input example:

assert sortedSquares([-5, -3, -2, -1]) == [1, 4, 9, 25]

But it's not working for this:

assert sortedSquares([-3, 0, 2]) == [0, 4, 9]

Somehow the ELIF statement was skipped during the first iteration. But when I changed bitwise & operator to logical AND in the IF statement - it started to work.

Could someone please explain what's going on here?

Sorry if it's a duplicate. I have been trying to find an explanation but found nothing.

CodePudding user response:

The behavior is not strange. You should check Operator precedence. You missed (...) & (...):

if nums[pointer] > abs(nums[0]) & nums[pointer-1] < abs(nums[0]):

should be

if (nums[pointer] > abs(nums[0])) & (nums[pointer-1] < abs(nums[0])):
#  ^---        HERE          ---^   ^---        HERE            ---^

Output

# Before
>>> sortedSquares([-3, 0, 2])
[0, 9, 4]

# After
>>> sortedSquares([-3, 0, 2])
[0, 4, 9]

CodePudding user response:

As described in the documentation, & has higher precedence than > and <. Thus

nums[pointer] > abs(nums[0]) & nums[pointer-1] < abs(nums[0])

is evaluated as

nums[pointer] > (abs(nums[0]) & nums[pointer-1]) < abs(nums[0])

which is not the same as when you use (the correct) logical and, as that has lower precedence than > and < and thus the statement evaluates as you expect as:

(nums[pointer] > abs(nums[0])) and (nums[pointer-1] < abs(nums[0]))
  • Related