0

I've been trying to understand how name lookup works in python and have been messing with the global dictionary and stumbled upon something that confused me

>>> glob_dict=globals()
>>> glob_items=glob_dict.items()
>>> glob_list=list(glob_items)
>>> user_dict={'a':1,'b':2,'c':3}
>>> user_items=user_dict.items()
>>> user_list=list(user_items)
>>> user_dict['d']=4
>>> user_list
[('a', 1), ('b', 2), ('c', 3)]
>>> glob_list
 ... 'user_list': [('a', 1), ('b', 2), ('c', 3)]}), ('glob_items', ...), ('glob_list', 
[...]), ('user_dict', {'a': 1, 'b': 2, 'c': 3, 'd': 4}), ('user_items', dict_items([('a', 
1), ('b', 2), ('c', 3), ('d', 4)])), ('user_list', [('a', 1), ('b', 2), ('c', 3)])]))]

There were a lot of items in glob_list so I removed most for purposes of reading. Notice how in glob_list when an item is added in the global dictionary, it is updated in the list seen by the appearance of'user_list' or 'user_items' or any other values really when I tried updating it. In the user dictionary, the list remains the same though user_items is updated

dict_items([('a', 1), ('b', 2), ('c', 3), ('d', 4)])

What causes this difference? I also feel like I don't really understand dict_items very well so this may add to the confusion. I (think I) understand name binding rules and the difference between mutable and immutable types. At first I thought that glob_list was referencing the still stored glob_items which is mutable which was why it was updating. But then the same thing didn't occur for the user_list so I am thoroughly confused. Why is there a difference and what is going on?

Colin Hicks
  • 348
  • 1
  • 3
  • 13
  • `dict.items()` return a _Dictionary view_ object which provides a dynamic view of the dictionary's items. – martineau Apr 28 '20 at 19:27
  • right, and both glob_items and user_items are updated dynamically. When I use glob_items to create a list: glob_list=list(glob_items), this list is also updated dynamically. When I use user_items to make a list: user_list=list(user_items), the list isn't updated when user_dict and user_items are updated (mutated). Why is there a difference for globals? – Colin Hicks Apr 28 '20 at 19:31
  • I wouldn't expect any `list` to be dynamically updated once created — there are no "List views" that I know of — so I think you need to double check that. Note variables are just names of objects, so if `a` is a list, so something like `a = b` only makes an alias for the same object that `a` refers to. – martineau Apr 28 '20 at 19:42
  • ``` >>> glob_dict=globals() >>> glob_items=glob_dict.items() >>> glob_list=list(glob_items) >>> glob_list ... 'glob_dict': {...}, 'glob_items': ..., 'glob_list': [...]}), ('glob_items', ...), ('glob_list', [...])]))] >>> a=5 >>> glob_list ....'glob_dict': {...}, 'glob_items': ..., 'glob_list': [...], 'a': 5}), ('glob_items', ...), ('glob_list', [...]), ('a', 5)]))] >>> type(glob_list) ``` notice how 'a' appears in the list after updating. Also it seems that glob_list really is a list from the last input – Colin Hicks Apr 28 '20 at 19:48
  • Try it using `glob_list=list(glob_items())` and `user_list=list(user_items())`, which will make non-dynamic copies of them. – martineau Apr 28 '20 at 20:01
  • glob_items isn't callable – Colin Hicks Apr 28 '20 at 20:04
  • Sorry, should have said `user_items = list(user_dict.items())`. The point was to use `list(dictionary.items())` instead of `list(dictionary.items)`. – martineau Apr 28 '20 at 20:08
  • It doesn't update, but why? What is the difference and what happened in the first case? – Colin Hicks Apr 28 '20 at 20:16
  • 1
    `items` is a dictionary method and trying to do `list(dictionary.item)` should be giving you a `TypeError: 'builtin_function_or_method' object is not iterable`. Doing `dictionary.items()` calls the method which returns a iterable object, which the `list` constructor then iterates over and stores the values it gets into the list being created (which will be the contents of the dictionary _at that point in time_ - as in not dynamic) – martineau Apr 28 '20 at 20:55

0 Answers0