0

When I am printing the iterator object I am getting <list_iterator at 0x103b1b278> but when I am doing id (my_iter) I am getting 4356944504. Should not the value be the same in both the cases 0x103b1b278 and 4356944504 (are different)? When I am printing the individual value of the iterator object b=next(my_iter). I am getting an id value of 4310934928. Can you please explain why am I getting a different value?

my_list=[1,2,3,4,5]
my_iter=iter(my_list)
my_iter
<list_iterator at 0x103b1b278>
id (my_iter)
4356944504
b=next(my_iter)
4310934928
Juan C
  • 5,846
  • 2
  • 17
  • 51
  • 4
    `hex(4356944504) == "0x103b1b278"` – Gennady Kandaurov May 07 '19 at 20:20
  • Is the second id the result of `id(b)` or `id(my_iter)`? – C.Nivs May 07 '19 at 20:26
  • @GennadyKandaurov thank you. One more question do instance variables have the same memory address. For eg, I have a person object p with instance variable age, weight. Will they have the same memory address as they are inside the person object p. In the example above if I do c=next(my_iter) it will have an id value different than that of my_iter object and b. But b and c are part of the iterator object ideally they should have the same memory address as that of my_iter object – Chyanit Singh May 07 '19 at 20:30
  • @C.Nivs my_iter id value 4356944504 and b id value 4310934928 – Chyanit Singh May 07 '19 at 20:33
  • @ChyanitSingh [this](https://nedbatchelder.com/text/names.html) article can provide some really good insight of how names and objects are managed in python. Some of it may seem elementary, but going back to basics can be helpful – C.Nivs May 08 '19 at 16:58

1 Answers1

1

The reason is that iter(my_list) and next(my_iter) are different objects. my_iter is the iterator itself, whereas next(my_iter) is a value yielded/produced by the iterator.

x = [1,2,3,4,5]
my_iter = iter(x)
type(my_iter)
# <class 'list_iterator'>

# This is a different object
type(next(my_iter))
# <class 'int'>

Moreover, the id of each object yielded by next(my_iter) is the id of the corresponding value in the list

id(next(my_iter))
4405200304

id(x[0])
4405200304

The way for id(b) to be the same as id(my_iter) is if b is my_iter, thus they are names referring to the same object:

x = [1,2,3,4,5]
my_iter = iter(x)

# b is now the same as my_iter, they refer to the same object
b = my_iter

id(my_iter)
4413711920

id(b)
4413711920

It's easy to get caught up in id representing memory addresses, it's best to try to ignore that and think of how names are bound to objects in python. I have fallen into this trap many times, as shown in the comments thread of this question, where chepner and juanpa give really good explanations of how this works in python (while dealing with my ignorance, at that)

An instance variable in a class is also a different object than the class. A reference to it is held in the instance dictionary, but again, the class and instance variable are two completely different objects.

As an example:

a = 1

x = list(range(5))

id(a) == id(x[1])
# True

The memory management under the hood of python is different. Even though I have instantiated a and x separately, a and x[1] share the same id because the memory for those objects was re-used. x[1] is another name/variable bound to the value 1, just like a is. This even happens with instance vars:

class Test:
    def __init__(self):
        self.a = 5

x = 5
c = Test()

id(x)==id(c.a)
True
C.Nivs
  • 12,353
  • 2
  • 19
  • 44