67

David Beazley のつぶやきのおかげで、新しいPython 3.6 の f-stringもネストできることが最近わかりました。

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************$478.23'

または:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'

これが可能であることに驚いていますが、ネストされた f-strings が役立つのはいつですか? これはどのようなユースケースに対応できますか?

注: PEP 自体は f-string のネストについて言及していませんが、特定のテスト ケースがあります。

4

13 に答える 13

12

これは、同じ行で書式設定パラメーターを渡すことで、 f-strings の使用を簡素化するためだと思います。

例えば:

>>> import decimal
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result:      12.35'

もちろん、プログラマーは絶対に読めないコードを書くことができますが、それは目的ではありません:)

于 2016-12-25T13:22:33.650 に答える
1

ネストされた f-string とフォーマット指定子の評価された式

この質問は、「外側の」f文字列の評価された式の中でf文字列を使用する動機となるユースケースに関するものです。

これは、評価された式をf-stringの書式指定子内に表示できる機能とは異なります。この後者の機能は非常に便利で、(1) ネストされた中括弧が含まれているため、人々がこの投稿を見ている理由である可能性があり、(2) ネストされた f-strings がそのままフォーマット指定子内で許可されているため、この質問に多少関連しています。 f-string のその他のカーリー式内。

F 文字列の入れ子はワンライナーに役立ちます

確かにネストされた f-string を許可する動機ではありませんが、「ワンライナー」が必要または必要なあいまいなケース (ラムダ式、内包表記、python -cターミナルからのコマンドなど) では、ネストが役立つ場合があります。例えば:

print('\n'.join([f"length of {x/3:g}{'.'*(11 - len(f'{x/3:g}'))}{len(f'{x/3:g}')}" for x in range(10)]))

ワンライナーが必要ない場合は、事前に変数を定義してから、f-string の評価された式で変数名を使用することで、構文のネストを置き換えることができます (ほとんどの場合ではないにしても、多くの場合、ネストされていないバージョンより読みやすく、維持しやすいでしょう; ただし、変数名を考え出す必要があります):

for x in range(10):
    to_show = f"{x/3:g}"
    string_length = len(to_show)
    padding = '.' * (11 - string_length)
    print(f"length of {to_show}{padding}{string_length}")

ネストされた評価された式 (つまり、フォーマット指定子内) は便利です

真の f-string ネストとは対照的に、f-stringの「フォーマット指定子」内で評価された式を許可する関連機能は、(他の人が指摘したように) 次のようないくつかの理由で非常に役立ちます。

  1. フォーマットは、複数の f-string または評価された式で共有できます
  2. フォーマットには、実行ごとに異なる計算量を含めることができます

ネストされた評価された式を使用するが、ネストされた f-stringを使用しない例を次に示します。

import random

results = [[i, *[random.random()] * 3] for i in range(10)]
format = "2.2f"

print("category,precision,recall,f1")
for cat, precision, recall, f1 in results:
    print(f"{cat},{precision:{format}},{recall:{format}},{f1:{format}}")

ただし、この入れ子の使用でも、構文上の入れ子を必要としない、より柔軟な (そしておそらくよりクリーンな) コードに置き換えることができます。

import random

results = [[i, *[random.random()] * 3] for i in range(10)]
def format(x):
    return f"{x:2.2f}"

print("category,precision,recall,f1")
for cat, precision, recall, f1 in results:
    print(f"{cat},{format(precision)},{format(recall)},{format(f1)}")
于 2021-08-07T18:38:41.820 に答える