通过元组列表时格式说明符如何取值 [英] how format specifier taking value while tuple list is passed
问题描述
我有一段代码如下:
tupvalue = [('html', 96), ('css', 115), ('map', 82)]
因此,当以所需格式为特定索引打印上述元组时,我发现了这样的代码:
So while printing the above tuple in the desired format for a particular index I found a code like this:
>>> '%s:%d' % tupvalue[0]
'html:96'
我想知道格式说明符'%s:%d'
如何将单个值tupvalue[0]
识别为两个值的元组吗?请通过文档参考说明此机制.
I'm wondering how the single value tupvalue[0]
is recognised as a tuple of two values by the format specifier '%s:%d'
? Please explain this mechanism with a documentation reference.
如何使用理解力以所需的格式将tupvalue
中的所有值格式化,如所示示例所示?
How can I use a comprehension to format all the values in tupvalue
in the required format as in the example shown?
推荐答案
首先,一个简单的问题:
First, the easy question:
如何使用理解力以所需的格式将
tupvalue
中的所有值格式化,如所示示例所示?
How can I use a comprehension to format all the values in
tupvalue
in the required format as in the example shown?
这是一个列表理解:['%s:%d' % t for t in tupvalue]
现在,更困难的问题了!
Now, the harder question!
格式说明符
'%s:%d'
如何将单个值tupvalue[0]
识别为两个值的元组?
how the single value
tupvalue[0]
is recognised as a tuple of two values by the format specifier'%s:%d'
?
您的直觉是这里发生了一些奇怪的事情,这是正确的. 组合语以特殊的语言显示,用于字符串格式.
Your intuition that something a bit strange is going on here is correct. Tuples are special-cased in the language for use with string formatting.
>>> '%s:%d' % ('css', 115) # tuple is seen as two elements
'css:115'
>>> '%s:%d' % ['css', 115] # list is just seen as one object!
TypeError: not enough arguments for format string
百分比样式的字符串格式设置不正确.因此,如果您实际上想格式化一个元组,则必须将其包装在另一个元组中,这与任何其他类型的对象不同:
The percent-style string formatting does not duck-type properly. So, if you actually wanted to format a tuple, you'll have to wrap it in another tuple, unlike any other kind of object:
>>> '%s' % []
'[]'
>>> '%s' % ((),)
'()'
>>> '%s' % ()
TypeError: not enough arguments for format string
文档的相关部分位于 4.7.2. printf
样式的字符串格式,其中提到:
The relevant section of the documentation is at section 4.7.2. printf
-style String Formatting, where it is mentioned:
如果format需要单个参数,则值可以是单个非元组对象.否则,值必须是一个元组,且其元组的数量必须与格式字符串指定的数量完全相同
If format requires a single argument, values may be a single non-tuple object. Otherwise, values must be a tuple with exactly the number of items specified by the format string
元组的奇怪处理是文档那部分开头的注释中提到的怪癖之一,也是推荐使用较新的字符串格式方法str.format
的原因之一.
The odd handling of tuples is one of the quirks called out in the note at the beginning of that section of the documentation, and one of the reasons that the newer string formatting method str.format
is recommended instead.
请注意,字符串格式的处理发生在运行时 †.您可以使用抽象语法树对此进行验证:
Note that the handling of the string formatting happens at runtime†. You can verify this with the abstract syntax tree:
>>> import ast
>>> ast.dump(ast.parse('"%s" % val'))
"Module(body=[Expr(value=BinOp(left=Str(s='%s'), op=Mod(), right=Name(id='val', ctx=Load())))])"
'%s' % val
解析为'%s'
和val
上的二进制操作,该操作在BINARY_MODULO
操作码的CPython中像str.__mod__(val)
一样处理.这意味着通常由str
类型决定接收到的val
不正确的 * 时该怎么做,只有在表达式被评估后才会发生,即一旦口译员到达那条线.因此,val
是错误的类型还是元素太少/太多都没有关系-这是运行时错误,而不是语法错误.
'%s' % val
parses to a binary operation on '%s'
and val
, which is handled like str.__mod__(val)
, in CPython that's a BINARY_MODULO
opcode. This means it's usually up to the str
type to decide what to do when the val
received is incorrect*, which occurs only once the expression is evaluated, i.e. once the interpreter has reached that line. So, it doesn't really matter whether the val
is the wrong type or has too few/too many elements - that's a runtime error, not a syntax error.
† 除了在某些特殊情况下,CPython的窥孔优化器可以在编译时恒定折叠".
* 除非val
的类型子类str
,在这种情况下type(val).__rmod__
* Unless val
's type subclasses str
, in which case type(val).__rmod__
should be able to control the result.
这篇关于通过元组列表时格式说明符如何取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!