Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialKevin Faust
15,353 Pointspython challenge help
Hello,
my code doesn't seem to be working and i'm not sure why. I have this same code layout in workspaces and it works fine
from collections import OrderedDict
## Menu Items:
# 'n', 'new challenge'
# 's', 'new step'
# 'd', 'delete a challenge'
# 'e', 'edit a challenge'
menu = OrderedDict({
'n': 'new challenge',
's': 'new step',
'd': 'delete a challenge',
'e': 'edit a challenge',
})
3 Answers
Chris Freeman
Treehouse Moderator 68,457 PointsThe OP code will run because the OrderedDict
constructor accepts a single iterable which can be a dictionary. It fails because the order of the key/value pairs from this dictionary is not guaranteed.
>>> menu = OrderedDict({
...
... 'n': 'new challenge',
... 's': 'new step',
... 'd': 'delete a challenge',
... 'e': 'edit a challenge',
...
... })
>>> menu
OrderedDict([('n', 'new challenge'), ('e', 'edit a challenge'), ('s', 'new step'), ('d', 'delete a challenge')])
Simply changing the curly braces to square brackets is not sufficient because that is not legal syntax for a list. Turning each pair in to a tuple will satisfy this:
menu = OrderedDict([
( 'n', 'new challenge'),
('s', 'new step'),
('d', 'delete a challenge'),
('e', 'edit a challenge'),
])
produces
>>> menu = OrderedDict([
... ( 'n', 'new challenge'),
... ('s', 'new step'),
... ('d', 'delete a challenge'),
... ('e', 'edit a challenge'),
... ])
>>> menu
OrderedDict([('n', 'new challenge'), ('s', 'new step'), ('d', 'delete a challenge'), ('e', 'edit a challenge')])
The other post mentioned by Kevin Faust was about alternatives of specifying regular dicts. But thanks for the mention!
Steven Parker
231,275 PointsIt works in workspaces? I would think you'd need to put parentheses around each key/value pair, exchange the colons for commas, and change the braces into brackets.
Kevin Faust
15,353 Pointsyea it works in workspaces. and here was a post from Chris Freeman :
https://teamtreehouse.com/community/why-is-ordereddict-written-like-a-list
e = dict({'three': 3, 'one': 1, 'two': 2})
as you can see, what i entered in the solution and in workspaces is exactly that. yet for some reason the code challenge doesnt pass me
i know that i can pass if i use the following way:
from collections import OrderedDict
menu = OrderedDict([
('n': 'new challenge'),
('s': 'new step'),
('d': 'delete a challenge'),
('e': 'edit a challenge'),
])
but i found that way more harder to understand because we are creating a list of tuples and then changing that to a dict
Steven Parker
231,275 PointsI don't think that will pass the challenge. But it will if you change the colons into commas.
Chris certainly knows his Python. But it could be one of those cases where the challenge is looking specifically for a method that was introduced in the course, and something more advanced might not be recognized.
Kevin Faust
15,353 Pointsoh yea whoops
Steven Parker
231,275 PointsHey I found this:
"The OrderedDict constructor and update() method both accept keyword arguments, but their order is lost because Pythonβs function call semantics pass-in keyword arguments using a regular unordered dictionary"
That post you cited before was discussing regular dict's.
Kevin Faust
15,353 Pointsi also finally realize why this worked:
menu = OrderedDict({
'a': add_entry,
'v': view_entries
})
it gave off the false impression that this syntax was right because the hash ordering happened to keep the two keys in their right order. i added another key and i saw that no longer were the keys in order
Kevin Faust
15,353 PointsKevin Faust
15,353 Pointsthank you chris
when you say "It fails because the order of the key/value pairs from this dictionary is not guaranteed.", i dont understand what you mean.
and i still dont understand why my (wrong?) code works in workspaces
so only the tuple list would work in this case?
now that i think about it, i dont really understand what an OrderedDict is. Online, I read that it "remembers the order in which its contents are added." but what does that mean? It's not like everytime I loop through a dictionary, the values will be returned in a different order
no matter how hard i look at it, a normal dict and an ordereddict look the exact same to me
Chris Freeman
Treehouse Moderator 68,457 PointsChris Freeman
Treehouse Moderator 68,457 PointsAn
OrderedDict
iterates over it's argument to extract the key/value pairs. When using a dict as an argument, the key value pairs are presented back in an order determined by the hashed value of the key. The order is the same as seen when printing a dict:Revisiting the ways to specifying a
dict
from the other post, when a dictionary is presented as an argument the order of the key/value pairs is ordered by the hash. Using the same techniques from the other post:OrderedDict
oc
andod
work because the argument is alist
not adict
.So one lesson here is that if order of arguments is important, a dictionary won't do.
A
dict
and anOrderedDict
behave the same when referencing using a key. But the similarity ends there. Notice how when printed, anOrderedDict
presents differently and a truedict
. If an item is deleted from adict
then replaced the twodicts
would remain equal. If an item is removed from anOrderedDict
then replaced, the item goes at the "end" of theOrderedDict
so they wouldn't not be equal.Does that answer your questions?
Kevin Faust
15,353 PointsKevin Faust
15,353 Pointsthanks alot chris it is starting to make sense
So OrderedDicts are basically a list of tuples --> (key, value) <-- which are treated like a dictionary
normal dicts dont keep their order (as I have just learned) and so we use OrderedDicts if we want order to be kept. I was confused because "OrderedDicts" doesn't contain "actual" dicts but rather tuples which behave like dicts
What does ordering my hash mean?
What did you mean by: "If an item is deleted from a dict then replaced the two dicts would remain equal. If an item is removed from an OrderedDict then replaced, the item goes at the "end" of the OrderedDict so they wouldn't not be equal."?
Chris Freeman
Treehouse Moderator 68,457 PointsChris Freeman
Treehouse Moderator 68,457 PointsI would say the print string of an
OrderedDict
is an list of tuples. Internally,OrderedDict
has many methods available:clear
,copy
,fromkeys
,get
,items
,keys
,move_to_end
,pop
,popitem
,setdefault
,update
,values
"
If an item is deleted from a dict then replaced the two dicts would remain equal.
"Let's look at how
dicts
behave:If an item is removed from an OrderedDict then replaced, the item goes at the 'end' of the OrderedDict so they wouldn't not be equal.
Repeating the same for
OrderedDict
does not behave the same.Looking at the
.keys()
order ofdict1
,dict2
,orddict1
, andorddict2
shows the iteration order would be different:Kevin Faust
15,353 PointsKevin Faust
15,353 Pointsthank you. makes perfect sense now