decimus phostle
decimus phostle

Reputation: 1050

String formatting [str.format()] with a dictionary key which is a str() of a number

Python neophyte here. I was wondering if someone could help with the KeyError I am getting when using a dictionary for string interpolation in str.format.

dictionary = {'key1': 'val1', '1': 'val2'}

string1 = 'Interpolating {0[key1]}'.format(dictionary)
print string1

The above works fine and yields:

Interpolating val1

However doing the following:

dictionary = {'key1': 'val1', '1': 'val2'}

string2 = 'Interpolating {0[1]}'.format(dictionary)
print string2

results in:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    string2 = 'Interpolating {0[1]}'.format(dictionary)
KeyError: 1L

So the problem seems to be in the interpretation of the numeric key as a list index, IMHO. Is there any way to work around this? (i.e. convey that this is instead a dictionary key)

TIA and apologies if this question has been asked before(couldn't find anything relevant with my search-fu).

Edit 1: The key is not numeric as was erroneously noted, earlier. Instead it is a string representation of a number - as was pointed out by BrenBarn.

Upvotes: 15

Views: 28752

Answers (4)

Pulsar
Pulsar

Reputation: 288

If your dictionary keys are strings, a possible workaround is to convert your dictionary to a class:

class ClassFromDict:
    def __init__ (self, dct) :
        for key in dct.keys():
            self.__dict__[key] = dct[key]

dictionary = {'key1': 'val1', '1': 'val2'}
classfromdict = ClassFromDict(dictionary)

string1 = 'Interpolating {0.key1}'.format(classfromdict)
print string1
string2 = 'Interpolating {0.1}'.format(classfromdict)
print string2

Upvotes: -1

Flynn W.
Flynn W.

Reputation: 99

I think what you are looking for is:

dictionary = {'key1': 'val1', '1': 'val2'}
string2 = 'Interpolating {key1}'.format(**dictionary)
print string2

Upvotes: 9

Jon Clements
Jon Clements

Reputation: 142256

You're right - the parser isn't that complex, and can't handle variable subscripts for dictionaries. Your work around is:

string2 = 'Interpolating {somevar}'.format(whateverhere..., somevar=dictionary['1'])

Upvotes: -1

BrenBarn
BrenBarn

Reputation: 251598

No. According to the documentation:

Because arg_name is not quote-delimited, it is not possible to specify arbitrary dictionary keys (e.g., the strings '10' or ':-]') within a format string.

So you can't use strings consisting of numbers as dictionary keys in format strings.

Note that your key isn't numeric, and it's not trying to use it as a list index. Your key is a string that happens to contain a digit character. What it's trying to do is use the number 1 (not the string "1") as a dictionary key. It will work if you use the number 1 as your dictionary key (i.e., make your dict {'key1': 'val1', 1: 'val2'}).

Upvotes: 15

Related Questions