Bit wise modification of integers in Python

The program that I'm writing, manipulating integers, applying to them the binary operation (eg >>

, &

, |

). Many of the operations are applied within functions, and so that the results of the operations persist after the function returns, I return a copy of the changed variable.

Something like:

updated = applyOp(original, amnt)

def applyOp(original, amnt):
    return original >> amnt

      

If I didn't want to return a copy of the integer and instead wanted the changes made to original

within the function to be persisted outside the function, I suppose I could create a wrapper class of some kind. Are there any other options? Perhaps the ones that specifically make it easier to manipulate bitwise integers?

+3


source to share


2 answers


In Python, assigning to a variable changes the binding of the variable, not the value at a specific memory location. To allow modification of the way you described, I believe you will need to modify the stored data, not bind variables. Let's take the following example:

a = 1
b = a
a = 2

      

Since the assignment changes the binding of the variable, it is a

now bound to 2

, but b

still bound to 1

. You really want the opposite behavior, but (as far as I know) this behavior is not available in Python.

As you correctly say, this will require some kind of wrapper. However, a class is not absolutely necessary for this purpose. One of the easiest ways to do this is to list your data. Take this example:

a = [1]
b = a
a[0] = 2

      



Now a

and b

still contain the same list (since there was no remapping for them) and so a[0] == b[0] == 2

. So one correct solution is to always pass the list of elements to the function only, and not directly pass the value.

Another answer might be to share data between functions by making both methods of the same class, which of course can share member variables. However, I cannot tell from your limited information if this approach is right for you.

Here's an example of how this could potentially work:

class MyClass:
    def __init__(self):
        self._value = 0;

    def do_something(self):
        # Do something with self._value
        self._helper_function()
        # Continue using self._value

    def _helper_function(self):
        # No need to pass the value in. It is accessible at self._value

      

Again, whether this will work depends on what you are trying to do.

+2


source


I am assuming that you are coming from a language like C and have not yet become familiar with the internals of Python.

In python, all objects are passed by reference. This means that no copying occurs when you call the function. You can check this by looking at the id (memory location) of your objects:

x = 0

print(id(x))

def f(y):
    print(id(y))

f(x)

      

In both cases, the identifier is the same, so they are actually the same object and not a copy.

It sounds funny at first, because how would the meaning change?



x = 1
print(id(x))
x += 2
print(id(x))

      

As you can see, the ID has changed. Instead of increasing x, we got a completely new object! This is because it int

is an immutable type.

This means that when an operation is performed on an object, it returns a new object instead of modifying itself. The opposite is a mutable type that can modify itself.

Types for python str

, float

, int

and tuple

unchangeable, and types dict

, list

and set

mutability.

Be that as it may, I would advise you to worry less about implementation details and minimal differences in performance, even if it prevents you from worrying about such things. Make the code workable and read it first, and take care of potential performance issues if they do occur.

0


source







All Articles