Guide Python Beginner

9.13 Best Practices

Reaching for join() instead of += in loops, f-strings as the default formatting choice, comparing strings with == rather than is, and parsing untrusted text with the standard library instead of eval().

2 min read

Build Large Strings with join(), Not +=

Accumulating a string with += inside a loop is O(n²); collecting pieces in a list and calling "".join(...) once is O(n). See 9.11 Memory and Performance for the full explanation.

result = " ".join(word_list)     # preferred over looped += 

Default to f-Strings, but Know the Exceptions

f-strings are the fastest and most readable choice for new code — but only when the template itself is a literal in the source. If the template is loaded from a config file or comes from an untrusted source, use .format() or string.Template instead (see 9.6 String Formatting).

Compare Content with ==, Never Identity with is

String interning is a CPython implementation detail, not a language guarantee — two equal strings built at runtime are not guaranteed to be the same object. Always compare string content with ==.

>>> a = "hello"; b = "".join(["h", "e", "l", "l", "o"])
>>> a == b, a is b
(True, False)     # equal content, but NOT the same object

Parse Structured Data with the Standard Library, Not eval()

Use json.loads(), ast.literal_eval(), or yaml.safe_load() to parse data — never eval(), which executes arbitrary code and is a serious security risk on any input that isn’t fully trusted.

Specify Encoding Explicitly

Always pass an explicit encoding="utf-8" (or whatever is correct) when reading or writing files, rather than relying on the platform default — the default varies by OS and can silently corrupt non-ASCII text.

Quick Interview Answer

“Five habits cover most of what matters day to day: build large strings with ''.join(...) instead of += in a loop; default to f-strings for new code, but fall back to .format()/string.Template when the template itself is data or untrusted; always compare strings with ==, never is, since interning isn’t a language guarantee; parse structured text with json.loads()/ast.literal_eval() rather than eval(), which is a security risk on untrusted input; and specify file encoding explicitly instead of relying on a platform default that can silently corrupt non-ASCII text.”

Common Mistakes

  • Reaching for eval() to parse a dict-like or list-like string instead of ast.literal_eval() or json.loads()eval() executes arbitrary code, which is unsafe on anything not fully trusted.
  • Opening a file with open(path) and no explicit encoding=, then hitting a UnicodeDecodeError or silent mojibake on a different OS or locale.
  • Relying on is for string comparison because it happened to work in a quick REPL test — interning behavior differs between short literals and runtime-built strings.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form