Master Python Numbers & Strings: Tips, Pitfalls, and Best Practices
This guide covers Python's core numeric and string types—including ints, floats, complex numbers, booleans, and bytes—explains common pitfalls like floating‑point precision, demonstrates formatting options, shows how to use enums and SQLAlchemy for cleaner code, and offers practical advice for readable and efficient scripting.
Basic Types
Numeric Foundations
Python has three built‑in numeric types: int, float, complex. Example:
# integer
score = 100
# float
temp = 37.2
# complex
com = 1 + 2jIntegers have arbitrary precision; even the maximum unsigned 64‑bit value can be used without overflow:
>> 2 ** 64 - 1
18446744073709551615
>>> 18446744073709551615 * 1000
18446744073709551615000Underscores can be used as visual separators:
i = 1_000_000
pi = 3.141_592_653_589_793
print(pi) # 3.141592653589793Floating‑Point Pitfalls
Floats are stored as binary fractions, so many decimal fractions cannot be represented exactly. The classic example:
print(0.1 + 0.2)
# 0.30000000000000004Python’s float is a 64‑bit double‑precision value with a 53‑bit mantissa; excess bits are rounded, causing tiny errors.
For exact decimal arithmetic, use the decimal module with string inputs:
from decimal import Decimal
Decimal('0.1') + Decimal('0.2')
# Decimal('0.3')Passing a float directly defeats the purpose because the float is already imprecise:
Decimal(0.1)
# Decimal('0.1000000000000000055511151231257827021181583404541015625')Booleans as Numbers
Booleans are a subclass of int: True equals 1 and False equals 0. This allows concise counting, e.g., counting even numbers in a list:
numbers = [1, 2, 4, 5, 7]
count = sum(i % 2 == 0 for i in numbers)
print(count) # 2Common String Operations
Strings are sequences; you can iterate, slice, and reverse them:
s = 'Hello, 中文'
for c in s:
print(c)
print(s[1:3]) # 'el'
print(s[::-1]) # '!dlrow olleH'Three main formatting styles exist in modern Python:
C‑style % formatting:
'Hello, %s' % name str.formatmethod: 'Hello, {}'.format(name) f‑strings (Python 3.6+): f'Hello, {name}' Example combining all three:
username, score = 'piglei', 100
print('Welcome %s, your score is %d' % (username, score))
print('Welcome {}, your score is {:d}'.format(username, score))
print(f'Welcome {username}, your score is {score:d}')Advanced String Methods
s.isdigit()– checks if all characters are digits. Example:
'123foo'.isdigit() # False str.split(sep)– splits the string by sep. Example:
'a:b'.split(':') # ['a', 'b'] str.partition(sep)– returns a tuple (before, sep, after). Example:
'a:b'.partition(':') # ('a', ':', 'b') str.translate(table)– replaces multiple characters efficiently. Example:
s = 'a,b.'
table = s.maketrans(',.', ',。')
s.translate(table) # 'a,b。'Strings vs Bytes
Unicode text strings ( str) and binary data ( bytes) are distinct. Convert with .encode() and .decode():
s = 'Hello, 世界'
b = s.encode('utf-8')
print(b) # b'Hello, \xe4\xb8\x96\xe7\x95\x8c'
print(b.decode('utf-8')) # 'Hello, 世界'Case Stories
Replacing Magic Numbers with Enums
Original code used raw integers to represent user types, making the logic hard to read:
def add_daily_points(user):
if user.type == 13:
return
if user.type == 3:
user.points += 120
return
user.points += 100
returnRefactored version introduces an Enum that also inherits from int for seamless comparison:
from enum import Enum
class UserType(int, Enum):
VIP = 3
BANNED = 13
DAILY_POINTS_REWARDS = 100
VIP_EXTRA_POINTS = 20
def add_daily_points(user):
if user.type == UserType.BANNED:
return
if user.type == UserType.VIP:
user.points += DAILY_POINTS_REWARDS + VIP_EXTRA_POINTS
return
user.points += DAILY_POINTS_REWARDS
returnBuilding SQL Safely
Legacy code concatenates raw SQL strings, which is error‑prone and hard to extend:
def fetch_users(conn, min_level=None, gender=None, has_membership=False, sort_field="created"):
statement = "SELECT id, name FROM users WHERE 1=1"
params = []
if min_level is not None:
statement += " AND level >= ?"
params.append(min_level)
if gender is not None:
statement += " AND gender = ?"
params.append(gender)
if has_membership:
statement += " AND has_membership = true"
else:
statement += " AND has_membership = false"
statement += " ORDER BY ?"
params.append(sort_field)
return list(conn.execute(statement, params))Using SQLAlchemy provides an object‑oriented query builder:
def fetch_users_v2(conn, min_level=None, has_membership=False, sort_field="created"):
query = select([users.c.id, users.c.name])
if min_level is not None:
query = query.where(users.c.level >= min_level)
query = query.where(users.c.has_membership == has_membership).order_by(users.c[sort_field])
return list(conn.execute(query))For non‑SQL templating, a template engine such as Jinja2 is recommended instead of manual string concatenation.
Programming Advice
Avoid Pre‑computing Literals
Writing a literal like 950400 directly or as 11 * 24 * 3600 yields identical performance because Python folds constant expressions at compile time.
Inspect Bytecode with dis
The dis module can show that the constant is loaded directly:
import dis
dis.dis(do_something)
# ... LOAD_CONST 950400 ...Improving Long‑String Readability
PEP 8 recommends limiting lines to 79 characters. For very long strings, use implicit concatenation inside parentheses or split the literal across lines:
s = (
"This is the first line of a long string, "
"this is the second line"
)When a multi‑line literal would break indentation, wrap it with textwrap.dedent to strip leading spaces:
from textwrap import dedent
message = dedent("""
Welcome, today's movie list:
- Jaw (1975)
- The Shining (1980)
- Saw (2004)
""")Right‑to‑Left String Methods
Methods prefixed with r (e.g., .rsplit(), .rpartition()) operate from the end of the string, which can be handy for certain parsing tasks.
Conclusion
Understanding Python’s basic types, their quirks, and idiomatic manipulation leads to clearer, safer, and more maintainable code. Leveraging enums, the decimal module, and higher‑level libraries like SQLAlchemy or Jinja2 helps avoid magic numbers, SQL injection, and unreadable string handling.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
