5

Python 3.8 allows for self-documenting expressions and debugging using =, e.g.:

print(f'{myvar=}')

Is it possible to print the output on a new line? This would be useful for variables with multi-line outputs like dataframes, e.g.

import pandas as pd

df = pd.DataFrame({'animal': ['alligator', 'bee', 'falcon', 'lion', 'monkey']})

print(f'{df=}')
df =
      animal
0  alligator
1        bee
2     falcon
3       lion
4     monkey
wjandrea
  • 28,235
  • 9
  • 60
  • 81
John
  • 949
  • 1
  • 9
  • 20

3 Answers3

4

If you make your f string triple-quoted, you can include a newline after the =:

print(f'''{df=
}''')
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
2

Using triple quotes works, but it causes some trouble when the print statement is in an indented block:

if True:
    if True:
        # ...some code with indentation...
        print(f"""{df =
}""")
        # ...more code with indentation...

Note that one does not simply indent the }""" part to the proper level, without breaking the formatting of the first line of the f-string.

Single line solution

I asked a similar question, and found a single line solution here, which I am writing here as well, for reference.

def f_str_nl(obj): return f"\n{obj!r}"

print(f"{f_str_nl(df) = !s}")

which outputs:

f_str_nl(df) = 
      animal
0  alligator
1        bee
2     falcon
3       lion
4     monkey

This method does not cause problems with indented blocks. However, the name of the object in the f-string gets wrapped with the function name, f_str_nl().

Enigma Machine
  • 123
  • 1
  • 7
  • 1
    I posted [my own single-line solution](/a/76335376/4518341), if you want to take a look :) It allows conversions and format specs. – wjandrea May 25 '23 at 19:20
  • 1
    [There's no good reason to use named lambdas](/q/38381556/4518341), use a `def` instead. – wjandrea Jul 25 '23 at 17:44
2

To include a newline inside the f-string, like in Patrick's answer, but have it in one line, I use eval:

print(eval('f"""{df=\n}"""'))
df=
      animal
0  alligator
1        bee
2     falcon
3       lion
4     monkey

Use triple-single quotes to allow single-quotes inside, for example:

print(eval('''f"""{df.query('animal.str.contains("e")')=\n}"""'''))
df.query('animal.str.contains("e")')=
   animal
1     bee
4  monkey

If you include a conversion, it needs to go after the newline (e.g. ...\n!s}...), otherwise you get a SyntaxError. Same for a format spec, but with a ValueError you'd get from a non-eval'd f-string.

I put it in a code snippet so I don't have to type/remember the whole thing every time. For VSCode:

"Dead-simple debug using f-string with newline before value": {
    "prefix": "debug-fstring-newline",
    "body": "print(eval('''f\"\"\"DEBUG: {${1:<expression>}=\\n${2:!${3:<conversion>}}${4::${5:<format_spec>}}}\"\"\"'''))",
},

P.S. I initially tried inserting a newline via a variable, but this syntax is invalid:

NL = '\n'
print(f"{df={NL}}")
wjandrea
  • 28,235
  • 9
  • 60
  • 81