Creating strings

A string is a sequence of Unicode characters. Single and double quotes are interchangeable; triple quotes span multiple lines:

a = 'single'
b = "double"
c = """This string
spans lines"""
d = "She said \"hi\""     # escape a quote with backslash
e = 'It\'s fine'
print(a, b, d, e, sep=" | ")
print(c)
single | double | She said "hi" | It's fine This string spans lines

Useful escape sequences: \n newline, \t tab, \\ backslash. Prefix with r for a raw string where backslashes are literal — handy for file paths and regular expressions: r"C:\new\folder".

Indexing and slicing

Every character has a position starting at 0. Negative positions count from the end. A slice s[start:stop:step] takes characters from start up to but not including stop:

s = "Python"
print(s[0], s[-1])      # first, last
print(s[0:3])           # Pyt
print(s[2:])            # thon
print(s[:2])            # Py
print(s[::2])           # Pto (every 2nd)
print(s[::-1])          # nohtyP (reversed)
print(len(s))
P n Pyt thon Py Pto nohtyP 6

Strings are immutable — s[0] = "J" raises TypeError. Build a new string instead: "J" + s[1:].

The string methods you will actually use

t = "  Hello, World  "
print(t.strip())               # remove surrounding whitespace
print(t.lower(), t.upper())
print(t.strip().title())
print("a,b,c".split(","))        # -> list
print("-".join(["x", "y", "z"]))  # list -> string
print("banana".count("a"))
print("banana".replace("a", "o"))
print("banana".find("nan"))      # index or -1
print("hello".startswith("he"), "hello".endswith("lo"))
print("42".isdigit(), "abc".isalpha())
print("py".center(10, "*"))
Hello, World hello, world HELLO, WORLD Hello, World ['a', 'b', 'c'] x-y-z 3 bonono 2 True True True True ****py****

Methods never change the original string; they return a new one. t.strip() on its own does nothing unless you keep the result: t = t.strip().

f-strings: the modern way to format

Since Python 3.6, f-strings are the clearest way to build text from values. Put f before the quote and expressions in braces:

name, score, pi = "Ada", 93.4567, 3.14159
print(f"{name} scored {score}")
print(f"{score:.1f}")          # 1 decimal place
print(f"{pi:.3f}")
print(f"{1234567:,}")          # thousands separators
print(f"{0.256:.0%}")          # percentage
print(f"{name:>10}|{name:<10}|{name:^10}|")   # alignment
print(f"{2 ** 10 = }")         # debug form (3.8+)
Ada scored 93.4567 93.5 3.142 1,234,567 26% Ada|Ada | Ada | 2 ** 10 = 1024

Older code uses "{} {}".format(a, b) or "%s %d" % (a, b). Both still work, but prefer f-strings for anything new.

Run the f-string examples on your phone — the Coding Python app runs real Python 3 on your phone, with examples, quizzes and challenges built in.
Get it free

Checking membership and comparing

email = "ada@example.com"
print("@" in email)
print("gmail" not in email)
print("apple" < "banana")     # alphabetical
print("Apple" == "apple", "Apple".lower() == "apple")
True True True False True

Common mistakes

  • Adding a number to a string. "Age: " + 27 raises TypeError. Use f"Age: {27}" or str(27).
  • Forgetting methods return new strings. Assign the result.
  • Off-by-one slices. The stop index is exclusive. s[0:3] is three characters, not four.
  • Comparing with different cases. Normalise with .lower() or .casefold() before comparing user input.

Next: numbers and operators.

Frequently asked questions

How do I reverse a string in Python?

Use slicing with a negative step: s[::-1]. There is no built-in reverse() method for strings.

What is the difference between split() and join()?

split() turns a string into a list by cutting at a separator; join() does the opposite, gluing a list of strings together with the separator you call it on.

Are Python strings mutable?

No. Strings are immutable. Every method returns a new string; the original is untouched.

How do I check if a string contains a substring?

Use the in operator: if 'cat' in text. To find where, use text.find('cat') which returns the index or -1.