The reason for the above scenario is that tensors are mutable objects therefore they are changeable in-place
This implies that when you call b(a), instead of a new local variable a being created in the function scope, a ‘reference’ to a will be made and a[0] will be assigned the value 3.
However if a wasn’t a mutable object (not changeable in-place) the reverse would happen.i.e a new variable a would be created in the function scope and thus not affecting the outer a variable.
For instance, the function below doesn’t change the outer/global a
a = 0
def my_function(b):
    b = 3
    print(b)

my_function(a)
print(a)