Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
644 views
in Technique[技术] by (71.8m points)

python - Using dictionaries and compound field format() with Integer key stored as String

If a dictionary has an integer key stored as a string {'0': 'foo'} how would you reference that in Compound Field Names using .format()?

I get that it may be un-pythonic (and bad programming) to have a dict with such keys...but in this case, it's also not possible to use this way:

>>> a_dict = {0: 'int zero',
...           '0': 'string zero',
...           '0start': 'starts with zero'}
>>> a_dict
{0: 'int zero', '0': 'string zero', '0start': 'starts with zero'}
>>> a_dict[0]
'int zero'
>>> a_dict['0']
'string zero'
>>> " 0  is {0[0]}".format(a_dict)
' 0  is int zero'
>>> "'0' is {0['0']}".format(a_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: "'0'"
>>> "'0start' is {0[0start]}".format(a_dict)
"'0start' is starts with zero"

{0[0]}.format(a_dict) will always refer to the key int 0 even if there isn't one, so at least that's consistent:

>>> del a_dict[0]
>>> a_dict
{'0': 'string zero', '0start': 'starts with zero'}
>>> "{0[0]}".format(a_dict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 0L

(And yes, I know I could just do '%s' % a_dict['0'] if required.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

str.format, unlike e.g. "f-strings", doesn't use the full parser. To pull out the relevant bits of the grammar:

replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
element_index     ::=  digit+ | index_string
index_string      ::=  <any source character except "]"> +

A field_name surrounded by square brackets is an element_index, which is either:

  1. one or more digits (digit+, like 0 - but only if they're all digits, which is why 0start falls into the second case); or
  2. a sequence of "any source character except "]"".

Therefore for 0['0'] the field_name is "'0'", not '0'.

... an expression of the form '[index]' does an index lookup using __getitem__().

For "'0' is {0['0']}".format(a_dict) the replacement is a_dict.__getitem__("'0'"), and there's no way within the grammar to select the actual a_dict['0'].


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...