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 trial
Saad Aleem
6,089 PointsKeyError, even though the key exists.
Following is the code
values = { (0,0) : "_", (0,1) : "_", (0,2) : "_",
(1,0) : "_", (1,1) : "_", (1,2) : "_",
(2,0) : "_", (2,1) : "_", (2,2) : "_" }
def draw_matrix():
matrix = "\t ___ ___ ___\n\t|_{(0,0)}_|_{(0,1)}_|_{(0,2)}_|\n\t|_{(1,0)}_|_{(1,1)}_|_{(1,2)}_|\n\t|_{(2,0)}_|_{(2,1)}_|_{(2,2)}_|"
print(matrix.format(**values))
print("\nUse numpad keys to enter your mark")
draw_matrix()
When I access values of keys individually, it works fine. But, I can't unpack this dictionary using .format() for some reason.
KeyError: '(0,0)
It's the same if I use numbers. This is gonna be a tic-tac-toe game so I used the numpad keys previously. I cannot use the tuples as strings because I'll need to use them to check for winning conditions. That works perfectly, though.
1 Answer
Chris Freeman
Treehouse Moderator 68,468 PointsWhile tuples can be used as dictionaries keys due to having a unique hash value ( (0,0).__hash__() ), they can not be used in places that require an identifier. Though using ** for expanding dictionaries into key, value pairs works in many places, it will not work in this case. What it translate to would be this failed format:
"string with format {}".format( (0,0)='tuple' ) # <-- Keyword can't be an expression
It is the unique hash value of a tuple that does allow it to be a valid key in the {(0,0)} expression, which is why you get a KeyError: When looking up the valid key in the format() arguments, the key is not found.
Similarly, you can't use a tuple as an identifier in a function declaration:
def tmp( (0,0)=None):
print("this function will not work")
Numbers, instead of tuples won't work for one of two reason. As format() arguments you can't assign to a literal: 2 = "_", and numbers as format field names {2} become positional arguments. In this case, the {2} would be replaced with the 3rd argument.
Saad Aleem
6,089 PointsSaad Aleem
6,089 PointsThe keys do work individually
values[(0,0)] #this worksCan you elaborate a bit more on the positional argument point?
I did find a solution to this. It works perfectly If i convert the keys into strings at runtime within format()
Chris Freeman
Treehouse Moderator 68,468 PointsChris Freeman
Treehouse Moderator 68,468 PointsYou can order the arguments used to fill format fields in three ways:
"First goes here {}, second goes here, {}, etc.".format("thing1", "thing2")"First goes here {first}, second goes here, {second}, etc.".format(second="thing2", first="thing1")"Position 1 here {1}, position 0 here, {0}, etc.".format("zero_thing", "one_thing")Positional field name arguments in a format statement are numbered to represent the order within the argument list.
{0}is replaced with the first item,{1}is replaced with the second.In most cases, coders order the arguments in the order they being used so positional arguments aren't necessary. A neat usage of positional field names (and named fields) is when you want to repeat a field. This:
Can be replaced with: