-2

In short, I get the above error when attempting to loop through the key-value pairs in a dictionary. I know the fix, but not the reason why.

webuser = {
    "username": "JWick",
    "first": "John",
    "last": "Wick",
}

for key in webuser.items():
    print("\nKey: " + key)

Correct:

for key, value in webuser.items():
    print("\nKey: " + key)
    print("value: " + value)

Is this because I am attempting to loop through two values and only using one variable to store & output? That way, the program attempts to concatenate the data in the dictionary in the variable and fails.

Witek Bobrowski
  • 3,749
  • 1
  • 20
  • 34
Rahman
  • 21
  • 4
  • 3
    The reason why is because with `for key in webuser.items()` each value of `key` is a tuple since that is what the `items()` method of a dictionary returns. What don't you understand? – martineau Jul 03 '21 at 10:21
  • 1
    if you only want to get a key, you can always iterate over `.keys()` instead of `.items()` – Witek Bobrowski Jul 03 '21 at 10:24
  • 2
    @WitekBobrowski: If all you want is the keys you can just iterate over the dictionary directly: i.e. `for key in webuser:` – martineau Jul 03 '21 at 10:25
  • Thanks both, the book i'm using to learn didn't explain that the .items() method created a tuple which threw me off. Using .keys() will be useful in future so thank you for taking the time to respond. – Rahman Jul 03 '21 at 10:31
  • Does this answer your question? [Iterating over dictionaries using 'for' loops](https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops) – Life is complex Jul 03 '21 at 13:46

4 Answers4

2

In any iteration, .items() gives you a tuple which is (key, value) pair. If you do:

for k in webuser.items():
    ...

k becomes a tuple which is (key, value) Obviously you can't concatenate str and tuple. But if you do:

for k, v in webuser.items():
    ...

That tuple which gets back from .items() gets unpacked and the items inside it go into k and v and because they are str you can do concatenation.

Don't forget to print the for loop variables to see what's going on.

S.B
  • 13,077
  • 10
  • 22
  • 49
0

dict.items() contains tuples of (key,value) as elements that cannot be concatenated directly with strings. Look the the demo below for one iteration of the loop:

webuser = {
    "username": "JWick",
    "first": "John",
    "last": "Wick", 
}


for item in webuser.items():
    print(item)
    key, value = item
    print("\nKey: " + key)
    print("value: " + value)
    break

Output:

('username', 'JWick')

Key: username
value: JWick

This shows that the items are coming in as tuples. were are then using multiple assignment key, value = item to unpack the key and value. Instead, you can directly do:

for key, value in webuser.items():
    ...

In your original example you only wanted to iterate over keys. You can do that in the following two ways:

for key in webuser:
    ...

OR

for key in webuser.keys():
    ...

NOTE: As demonstrated in the first one, iterating over a dictionary iterates over it's keys by default.

Shubham
  • 1,310
  • 4
  • 13
0

To get a key in dictionary, there are 2 ways:

  1. Iterate over the dictionary: for key in webuser
  2. Use .keys() : for key in webuser.keys()

For getting the values of the dictionary: .values() is used for key in webuser.values()

For getting both the keys and values of the dictionary: items() is used. for key in webuser.items(). It returns a tuple.

When you don't use 2 variables, the tuple is not unpacked and it is assigned to variable key.

But for key,values in webuser.items(), the tuple is unpacked and the keys are assigned to key and values are assigned to values

0

Dictionary items() method returns a tuple of 2 elements for each iteration.

In short, a tuple is a data structure which is kind of an inmutable list of heterogeneous items (in the tuple each element represents a different concept while in a list they are all supposed to have the same nature. This is a good practice, not a technical limitation though). You can access to the items of a tuple by index, with the same notation you would do with a list.

So, you could get the same result with:

for item in webuser.items():
    print("key: " + item[0])
    print("value: " + item[1])

or

for item in webuser.items():
    print(f"key: {item[0]}; value: {item[1]}")

When you use 2 variables in the for assignment, Python is smart enough to positionally match each element of the tuple with the variables.

Iago Díaz
  • 368
  • 1
  • 2
  • 10