-1

I started reading the python documentation. I ended up with this statement:

Code that modifies a collection while iterating over that same collection can be tricky to get right. Instead, it is usually more straight-forward to loop over a copy of the collection or to create a new collection:

# Strategy:  Iterate over a copy
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

# Strategy:  Create a new collection
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

I can't understand the solution. How is this code working? I mean i get the idea of using one variable to iterate over a list but using two is complicated to understand. Source: https://docs.python.org/3/tutorial/controlflow.html#for-statements

  • Do you understand what `items()` returns? – Scott Hunter Apr 12 '20 at 17:16
  • 1
    From the context of the code, users.copy().items() returns a list of tuples, each containing a user and a status value. The documentation is saying it does not recommend deleting items or modifying a list while iterating over it. It causes confusion may be difficult to maintain. – Garret Apr 12 '20 at 17:20
  • **Example**:```users = {1:"inactive", 2:"active", 3:"active"} for user, status in users.copy().items(): if status == 'inactive': del users[user] print(users)``` **output**:```{2: 'active', 3: 'active'}``` – Sathvik Nov 19 '20 at 17:12

3 Answers3

1

this code iterate through user and status simultaneously: if the user status is 'inactive' the program will delete this user in the second for loop if the user is 'active' it will add this user to the active-users dictionary, when you want to loop through the key and value pair of a dictionary at the same time , you must use dict.items() method, the items() method allows you to loop through the items of each dictionary element (or tuple) at the same time, here the items are user and status that is why there are also 2 iteration variables also named user and status

eprisdetae
  • 34
  • 5
1

I had the same confusion. The example as given doesn't work. The piece that is missing is the dictionary object 'users' at the start. At that point in the tutorial we haven't been taught about them. https://docs.python.org/3/library/stdtypes.html#index-50

A working version is

users = { "John": "inactive", 
               "Helen": "active",
               "James": "active", # and so on...
            }

# Strategy:  Iterate over a copy
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

# Strategy:  Create a new collection
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

If you want to see the contents then you can print it out. Try this:

users = { "John": "inactive", 
               "Helen": "active",
               "James": "active", # and so on...
            }

# Strategy:  Iterate over a copy
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

print("Users after deleting.")
for user, status in users.items():
    print(user, status)

users = { "John": "inactive", 
               "Helen": "active",
               "James": "active", # and so on...
            }

# Strategy:  Create a new collection
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

print("active_users.items")
for user, status in active_users.items():
    print(user, status)
John
  • 11
  • 1
0

Simple example: imagine you have a physical phone book and want to look up friends or family in it. The equivalent in Python would be:

phone_book = { "Mom": "123-456-7890", 
               "Dad": "123-456-7891",
               "John Doe": "555-555-5555", # and so on...
            }

If you're attempting to look up your dad's phone number in your physical phone book, you'd do so by navigating directly to the page you wrote it on and finding the entry. Similarly, looking it up in a Python dictionary is the same:

print(phone_book['Dad']) # 123-456-7891

Now that the real-world example is pretty clear, look at your example. Through .items(), you're retrieving a key value pair where user is simply a key to reference a specific value in the users dictionary (like "Mom" or "Dad") and status is the value mapped to that specific user (like their phone numbers).

However, you're taking a copy of the users dictionary so that you can iterate over the entire pairing of users to statuses. If you had

for user, status in users.items():
   del[user]

you'd be modifying the dictionary you're attempting to iterate and would get an error. To avoid that, you're making a temporary copy of it to iterate through and remove the actual user from users (think "Remove Mom from your phone book").

In the second chunk, you are adding people to an active user dictionary. Think "Add Billy to phone book with phone number of "111-222-3344", but in this case, you're adding the user and their corresponding status.

TLDR: A dictionary is just a way to look things up, but in order to look something up, you need to know their identifier (name in phone book, user in user dictionary). If you want to do something with that identifier's value (number in phone book, status in user dictionary), you'd want to store it temporarily until you're done with it.

SteveK
  • 995
  • 5
  • 17