Why does "in" work for keys but not for strings?

I came across a very weird thing with strings and dictionaries in Python today. Can someone explain to me why the print statement works in the first for loop but fails in the second for loop?

test = 'ab'
test_dict = {}
test_dict[test] = 1

for x, y in test_dict:
    print('%s %s' % (x,y))

for x,y in test:
    print('%s %s' % (x,y))

Both loops are broken. The first one only happens to work due to the very specific coincidence that test is exactly two characters long, and so can be unpacked into two variables x and y.

To iterate over a dict's keys and values, write:

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

If you just want the keys you can do:

for k in d:
    ...

In detail, when you loop over a dict it iterates over the keys.

for x,y in test_dict

The dict has exactly one key, "ab". So on the first and only iteration, it assigns that string to x and y as if you'd written:

x,y = "ab"

As it happens, this is a valid unpacking. Two variables on the left, a two-item container on the right. x becomes "a" and y becomes "b".

If test were longer or shorter the first loop would also crash with either "need more than N values to unpack" or "too many values to unpack".

Why is the string unpacked in 1 scenario but not unpacked in the other?

The second loop iterates over the string "ab" directly. When you iterate over a string it breaks the string into single-character strings. The first iteration is "a" and the second is "b". On that first iteration, it tries to do:

x,y = "a"

This assignment fails with "need more than 1 value to unpack" because there are two variables on the left and only one character on the right.

The Covid-19 Riddle: Why Does the Virus Wallop Some Places and , Experts are trying to figure out why the coronavirus is so capricious. The answers could determine how to best protect ourselves and how long  Why definition, for what? for what reason, cause, or purpose?: Why did you behave so badly? See more.

For the dictionary case, you are iterating dictionary keys. for x, y in test_dict means "for each key in test_dict take the key and unpack to variables x and y". Since the only key is 'ab', the string is unpacked to x = 'a' and y = 'b'. Of course, this works specifically because your only string key has length 2.

For the string case, you are iterating a string. for x, y in test will fail. You can't say "for each character in test unpack to multiple variables" because a single character is not iterable. Instead, you will meet:

ValueError: not enough values to unpack (expected 2, got 1)

Why Does He Do That?: Inside the Minds of Angry , Amazon.com: Why Does He Do That?: Inside the Minds of Angry and Controlling Men eBook: Bancroft, Lundy: Kindle Store. Coronavirus patients are showing a wide range of symptoms and the exact reason why is still a mystery — but we do have some clues as to what factors can influence the severity of the disease. While the most common symptoms are fever, cough and shortness of breath, there are numerous reports of coronavirus patients experiencing nonrespiratory symptoms.

for x,y in test:
  print('%s %s' % (x,y))

since test is a list-like object (a string in python is list-like), iterating over it takes each character in turn. A character is not a list-like object of length 2, so trying to split it into x and y produces an error. If you had test = ("ab", "bc") then test would be a tuple containing pairs of characters, which could be split using the expression above. That's a very short answer, but I hope it clarifies what's going on.

The reason this works in the dict case is a little more complicated, but not very complicated. When you iterate over a dict in python, you actually iterate over its keys. This means that you have a list of one item, which is a string of length 2. As you saw above, a string of length 2 can be unpacked into its first and second characters, which is why the statement works.

Why does Belgium Exist? (Short Animated Documentary), Why does Belgium exist? A question which is often asked given its location between two Duration: 5:00 Posted: 2 days ago It’s one of the most contagious, uncontrollable actions a body does. There are many theories as to why people yawn. One popular theory is that yawning helps your body bring in more oxygen.

Why does the ocean appear blue? Isit because it reflects the color of , Scientific American is the essential guide to the most awe-inspiring advances in science and technology, explaining how they change our understanding of the  When you’re facing something you don’t want to do, it can make you feel tense. Putting off that dreaded chore is a way to get some short-term relief. The downside is that you’ll still have to tackle your task in the future, which may make you feel guilty or angry -- and cause your stress to rise more. If

Why Is President Trump Taking Hydroxychloroquine?, cwick (Chadwick Matlin, deputy editor): Clare, Kaleigh and Maggie, thanks for joining me to talk about the president's medicine cabinet. Answers to why you get goosebumps, hiccups, eye twitches, ringing in your ears, and the feeling of the hair on your neck standing up. Share on Facebook: http

Why does it suddenly feel like 1999 on the internet?, Is it a mirage, or has something really changed? It's not surprising that our online behavior would look somewhat different. The coronavirus has  An icon in the shape of a person's head and shoulders. It often indicates a user profile.

Comments
  • What is the full traceback?
  • The first print statement prints out: "a b" The second print statement is an error, as expected.
  • What do you think the y should print in the string case?
  • test is a string variable not a dictionary
  • "A dictonary is a collection of key-value pairs. x,y in this case is holding the key in x and the value in y" Not true, see previous comment.
  • I wouldn't necessarily say "broken"; the first loop is fine if you know the keys are two-character strings. But it does rely on that pretty specific assumption.
  • Why is the string unpacked in 1 scenario but not unpacked in the other?
  • @J.Mcclane, Because in one you are iterating dictionary keys (and the only key is iterable), the other you are iterating a string (and the characters in the string are not iterable). I've updated to clarify further.
  • In the second case, you're trying to unpack a single-character string "a". (for c in "ab" takes "a" and then "b", neither of which can be unpacked into x and y)