Python Forum

Full Version: Binding not explicitly declared happening
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everyone,


I'm basically new to Python. My experience is in industrial automation and some intermediate in MATLAB and, although I have developed good programming thinking, I need to clarify some things about Python. I'm trying to solve a problem from a course I'm taking, but I'm not posting this in the courses forum because the question is not even related to the problem description.

Here's the thing: I'm trying to have a list of that contains the alphabet letters (lower case) and another with the numbers from 0 to 25, so I can find a letter in the first list and know what's it's position. Probably I come up with a more efficient way of solving this, but I'm having some strange assignment to variables that I didn't expect. Have a look...

a = 0
c = list(range(26))
b = c
for i in 'abcdefghjiklmnopqrstuvwxyz':
    b [a] = i
    a += 1
After these lines are executed, c ends up containing the lower-case alphabet. Why? I assigned c to b before the loop, but I'm not reassigning anything to c. Where is this binding happening? If I print c before the loop, it has its numeric values.

Does this mean that, when you assign the value of a variable to another, they both get "married" and they'll always have the same value even when you only modify one of them?

Thanks in advance.
Lists are mutable objects. They are passed and assigned by reference not value. So c is a reference/pointer to a list. b = c makes b a reference/pointer to the same list. So when you make a change to b, you are making a change to the list b is pointing at, which is the same one c is pointing at. Typically you would solve this with a full slice (b = c[:]), which makes a shallow copy of c. In this case that would make b fully independent of c.

But I don't know why you are making the assignment anyway. If you are going to change all of the values in b, why initialize it to c in the first place?

A much simpler way to do this is:

c = list(range(26))
b = list('abcdefghjiklmnopqrstuvwxyz')
And slicing and indexing work on strings. If what you want is to find the index of a given character, you can just use:

b = 'abcdefghjiklmnopqrstuvwxyz'
b.index('f')
That is a bit inefficient, as it searches through the string to the letter each time. Better speed can be had with a dict:

b = {char: index for index, char in enumerate('abcdefghjiklmnopqrstuvwxyz')}
b['f']
(Aug-04-2019, 12:54 AM)ichabod801 Wrote: [ -> ]Lists are mutable objects. They are passed and assigned by reference not value. So c is a reference/pointer to a list. b = c makes b a reference/pointer to the same list. So when you make a change to b, you are making a change to the list b is pointing at, which is the same one c is pointing at. Typically you would solve this with a full slice (b = c[:]), which makes a shallow copy of c. In this case that would make b fully independent of c.

But I don't know why you are making the assignment anyway. If you are going to change all of the values in b, why initialize it to c in the first place?

A much simpler way to do this is:

c = list(range(26))
b = list('abcdefghjiklmnopqrstuvwxyz')
And slicing and indexing work on strings. If what you want is to find the index of a given character, you can just use:

b = 'abcdefghjiklmnopqrstuvwxyz'
b.index('f')
That is a bit inefficient, as it searches through the string to the letter each time. Better speed can be had with a dict:

b = {char: index for index, char in enumerate('abcdefghjiklmnopqrstuvwxyz')}
b['f']

Thank you very much, Craig. This was the answer I was looking for, and you actually taught me some new things. As I said, I'm really new to Python.

So, stating my understanding in my own words to make sure get it: When I do c = list(range(26)) I'm not creating a list and assigning it to a variable "c," but actually creating a list and setting "c" to be the pointer that will reference it. And when I do b = c I'm not creating a new list that's equal to the previously created but instead duplicating the pointer, thus accessing (reading or writing) the list every time I use any of both.

I understand your first example on how to find the index of a letter because it's just using a function but, for the second one, I'll need to check the documentation because I haven't gotten there yet. Still, it's really helpful.

My initialization of "b" wasn't very smart, I still need a lot of practice with the classes and types.

Again, thank you very much.
(Aug-04-2019, 03:33 AM)karkas Wrote: [ -> ]So, stating my understanding in my own words to make sure get it: When I do c = list(range(26)) I'm not creating a list and assigning it to a variable "c," but actually creating a list and setting "c" to be the pointer that will reference it. And when I do b = c I'm not creating a new list that's equal to the previously created but instead duplicating the pointer, thus accessing (reading or writing) the list every time I use any of both.

Correct.

(Aug-04-2019, 03:33 AM)karkas Wrote: [ -> ]I understand your first example on how to find the index of a letter because it's just using a function but, for the second one, I'll need to check the documentation because I haven't gotten there yet. Still, it's really helpful.

index is a method, which is a special type of function, specifically defined for a particular class. So b.index('f') is like calling index(b, 'f'), but you can only do it for classes that have defined an index method. The base sequences in python (str, list, and tuple) all have the index method. It returns the index in the sequence of the first instance of the parameter.
(Aug-04-2019, 07:51 AM)ichabod801 Wrote: [ -> ]index is a method, which is a special type of function, specifically defined for a particular class. So b.index('f') is like calling index(b, 'f'), but you can only do it for classes that have defined an index method. The base sequences in python (str, list, and tuple) all have the index method. It returns the index in the sequence of the first instance of the parameter.

Great. I'm getting into that. Thanks again, Craig. Really, really helpful.