【问题标题】:Python3.2 Str.format value repetitionPython3.2 Str.format 值重复
【发布时间】:2011-08-18 22:25:25
【问题描述】:

我正在为程序生成专门格式化的输入文件,并使用小型 python tkinter GUI 前端来执行此操作。旧代码使用 fortran 格式语句。除非已经有一组用于 python 的直接转换函数(我还没有找到),否则我认为 python 的格式可以完成这项工作。一般来说可以,但我找不到重复某个值的方法:

例如,在 fortran 中:

FORMAT (2A1, I3, **12I5**, F8.3, A7). The "12I5" statement translates to 12 integer values of width 5.

我知道我可以在格式调用中以文本形式包含 12 个项目(例如:...{0:5d}, {1:5d}, {2:5d}....),但我想知道是否有一种方法可以像上面的 fortran 示例那样简化形式。

有什么我遗漏的,或者这是不可能的,我必须明确地写出格式中的每一项?

-干杯, 克里斯。

编辑 这是我目前正在做的一个更清楚的例子:

>>> ---tester = ["M", "T", 1111, 2222, 234.23456, "testing"]    
>>> ---fmt = "{0:1}{1:1}, {2:3d}, {3:5d}, {4:8.3F}, {5:>7}"    
>>> ---print(fmt.format(*tester))    
MT,  13,  1234,  234.235, testing

我希望能够

>>> ---tester = ["M", "T", 1111, **2222, 3333, 4444**, 234.23456, "testing"]    
>>> ---fmt = "{0:1}{1:1}, {2:3d}, **3*{3:5d}**, {4:8.3F}, {5:>7}"    
>>> ---print(fmt.format(*tester))       

【问题讨论】:

    标签: python string format


    【解决方案1】:

    正如 ninjagecko 所建议的,您希望分段构建格式字符串。

    像我所做的那样使用隐式字段编号有助于简化这一点,尽管它不是绝对必要的(显式编号只会变得更加冗长,以确保数字对齐)。混合新旧字符串格式也意味着我们可以跳过一些繁琐的特殊字符转义。

    subfmt = ", ".join(["{:5d}"]*3)
    fmt = "{:1}{:1}, {:3d}, %s, {:8.3F}, {:>7}" % subfmt
    tester = ["M", "T", 1111, 2222, 3333, 4444, 234.23456, "testing"]
    
    >>> print(fmt)
    {:1}{:1}, {:3d}, {:5d}, {:5d}, {:5d}, {:8.3F}, {:>7}
    >>> print(fmt.format(*tester))
    MT, 1111,  2222,  3333,  4444,  234.235, testing
    

    【讨论】:

    • 太棒了。我不认为我真的知道 python 的 % 语法,这很好地解决了问题,谢谢大家。
    • 您可以感谢 Raymond Hettinger 向我介绍了这个特殊技巧。 %-formatting 语法实际上是在 3.x 中保留的“旧式”(Python 2.x)格式,因为删除它是一个向后兼容的噩梦,但对于这种情况它确实很方便。
    【解决方案2】:

    您可以像这样生成格式字符串的一部分(根据需要进行调整):

    >>> ','.join(['%s']*5)
    '%s,%s,%s,%s,%s'
    
    >>> ','.join(['%i']*5) % (1,2,3,4,5)
    '1,2,3,4,5'
    

    甚至像'%i '*10 一样(更简洁,如果您不介意末尾有一个额外的分隔符值)

    编辑: 以上内容已弃用,原始发帖人想要一个明确的示例,因此这里是一个明确的示例,其中 str.format (http://docs.python.org/library/stdtypes.html#str.format) 使用http://docs.python.org/library/string.html#formatstrings 中指定的格式。请注意,您可以做比这个演示更复杂的事情,例如使用漂亮的关键字参数甚至对象属性。请参阅文档。

    tester = ["M", "T", 1111, 2222, 3333, 4444, 234.23456, "testing"]
    fmt = "{}{}, {:3d}, " + 3*"{:5d}, " + "{:8.3F}, {:>7}"
    fmt.format(*tester)
    

    结果:

    'MT, 1111,  2222,  3333,  4444,  234.235, testing'
    

    (edit2:向 ncoghlan 道歉;在更新之前我没有看到他的新答案)

    【讨论】:

    • 感谢您的快速回复,但我不太确定这是否适合我所拥有的。我编辑了我的帖子以显示我目前在做什么。
    猜你喜欢
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2012-10-11
    • 2013-10-13
    相关资源
    最近更新 更多