Data Types I
Scalar values, text, conversion, and a first look at lists
Values and types
A value's type determines its available operations. Use type() to inspect it:
print(12 + 3) # 15
print("12" + "3") # 123
print(type(12)) # <class 'int'>
print(type("12")) # <class 'str'>| Type | Example | Common use |
|---|---|---|
int | 3, 125500 | Counts and exact whole numbers |
float | 0.125, 2.5 | Ratios and measurements |
bool | True, False | Decisions and flags |
str | "payments-worker" | Names, identifiers, text |
NoneType | None | An absent value |
complex | 3 + 4j | Real and imaginary components |
All these values are objects. Assignment binds a name to an object; reassignment changes what that name refers to:
workers = "3"
workers = int(workers)
print(workers) # 3
print(type(workers)) # <class 'int'>int() converts the text to an integer; it does not change the original string's type.
Integers
Integers support exact whole-number arithmetic:
| Operation | Expression | Result |
|---|---|---|
| Addition | 8 + 3 | 11 |
| Subtraction | 8 - 3 | 5 |
| Multiplication | 8 * 3 | 24 |
| Division | 8 / 3 | approximately 2.6667, a float |
| Floor division | 8 // 3 | 2 |
| Remainder | 8 % 3 | 2 |
| Exponentiation | 2 ** 10 | 1024 |
Multiplication and division take precedence over addition and subtraction. Use parentheses to change the grouping: 2 + 3 * 4 is 14; (2 + 3) * 4 is 20.
Comparisons such as <, >=, ==, and != produce booleans. = assigns; == compares:
workers = 3
capacity = workers * 20
occupied = 47
print(capacity - occupied) # 13 available slots
print(occupied < capacity) # TrueUse division and remainder when converting units:
timeout_ms = 125500
print(timeout_ms / 1000) # 125.5 seconds
print(timeout_ms // 1000) # 125 whole seconds
print(timeout_ms % 1000) # 500 remaining milliseconds/ produces a float. // rounds down; int() truncates toward zero, so -7 // 3 is -3 while int(-7 / 3) is -2. divmod(timeout_ms, 1000) returns the quotient and remainder together as a tuple, covered in Data Types II.
Python integers grow as needed, subject to memory. They do not silently wrap at a fixed 32-bit or 64-bit boundary, though a database or external format may impose its own limits.
Floats and conversion
Floats represent approximate real values, useful for ratios and measurements:
sample_rate = float(" 0.125 ")
print(800 * sample_rate) # 100.0
print(f"Sample rate: {sample_rate:.1%}") # Sample rate: 12.5%F-strings insert expressions inside braces. :.1% formats a ratio as a percentage with one decimal place; :.2f formats a number with two decimal places. Formatting changes the display, not the stored value.
Conversion rules depend on the input:
| Expression | Result |
|---|---|
int("12") | 12 |
int(3.5) | 3, truncated toward zero |
int("3.5") | Raises ValueError |
float("3.5") | 3.5 |
Complex numbers use j for the imaginary component. (3 + 4j).real is 3.0, .imag is 4.0, and abs(3 + 4j) is 5.0. They are used in areas such as signal processing and electrical calculations.
Booleans and missing values
Comparisons produce True or False. Combine conditions with and, or, and not:
workers = 3
sample_rate = 0.125
has_capacity = workers > 0
valid_rate = 0 <= sample_rate <= 1
print(has_capacity and valid_rate) # True
print(not has_capacity) # Falseand and or short-circuit: the right expression runs only when needed. They return an operand, which is not necessarily a boolean.
None represents absence. Keep it distinct from valid zero or false values:
fallback = None # Inherit the environment's routing default
workers = 0
enabled = False
print(fallback is None) # True
print(workers == 0, enabled is False) # True TrueUse is None for absence and == for ordinary value comparisons. is checks object identity.
bool(value) tests truthiness. Zero, empty strings and containers, and None are falsey; nonempty strings are truthy.
Strings
Strings are immutable sequences of Unicode code points. Single and double quotes both create strings; \n and \t represent a newline and tab. String methods return values without changing the original.
raw_name = " \tPayments-Worker\n"
name = raw_name.strip()
print(name) # Payments-Worker
print(raw_name == name) # False
print(name[0], name[-1], name[:8]) # P r PaymentsIndexes start at zero; negative indexes count from the end. A slice excludes its end position. An out-of-range index raises IndexError, while a slice can extend past the end. Indexing a string returns a string; Python has no separate character type.
Common operations:
print(" TrUe ".strip().lower()) # true
print(len("worker")) # 6
print("Worker" in "Payments-Worker") # True
print("api-worker".startswith("api-")) # True
print("settings.json".endswith(".json")) # True
print("worker_old".replace("_old", "_v2")) # worker_v2
print("svc-worker".removeprefix("svc-")) # workerNormalize case only when the field's rules allow it. .casefold() handles more Unicode cases than .lower() for case-insensitive matching.
.strip() removes whitespace from the ends. With an argument, it removes any of those characters, not an exact prefix or suffix. Use .removeprefix() or .removesuffix() for exact text.
Split text into a list, then join it
split() produces a list: an ordered sequence with indexed elements.
raw_labels = " api nightly\turgent "
cleaned = raw_labels.strip()
labels = cleaned.split()
print(labels) # ['api', 'nightly', 'urgent']
print(labels[0], len(labels)) # api 3
print(", ".join(labels)) # api, nightly, urgentWithout an argument, split() groups whitespace and omits empty fields. It already handles surrounding whitespace, so the preceding strip() is optional here.
join() inserts its separator between strings; every list element must be a string. An explicit split separator preserves empty fields:
print("east,,west".split(",")) # ['east', '', 'west']
print("".split()) # []
print(", ".join([])) # Empty lineAn empty list has nothing to index, but it can still be joined. Data Types II covers list updates and other containers.
Example: configuration values
Choose conversions by field: counts need arithmetic, identifiers need exact preservation, and textual flags need explicit interpretation.
name = " payments-worker ".strip()
deployment_id = "000042"
enabled = " TrUe ".strip().lower() == "true"
labels = " payments nightly ".split()
print(f"{name} [{deployment_id}]") # payments-worker [000042]
print(enabled, ", ".join(labels)) # True payments, nightlyThe same rules apply to environment variables, form fields, CSV cells, and command-line arguments.
Gotchas
Float precision
Binary64 floats cannot represent every integer beyond 2 ** 53 exactly:
identifier = 2 ** 53 + 1
transported = float(identifier)
print(int(transported)) # 9007199254740992
print(identifier - int(transported)) # 1
print(0.1 + 0.2 == 0.3) # FalseConverting back cannot recover lost precision. Keep identifiers as integers or strings across storage and transport. For measured quantities, compare floats using tolerances appropriate to the problem.
For money, integer minor units or Decimal may better match the contract. Construct decimals from text and specify rounding rules: rounding line items and rounding the total can produce different results.
Textual booleans
Truth testing does not parse a string's meaning:
print(bool("false")) # True: nonempty string
print(" FALSE ".strip().lower() == "true") # False
print(True + True) # 2: booleans act as integersThe comparison is sufficient only when input is known to be true or false. Unknown spellings need a separate validation policy. Likewise, a count API must decide whether to accept booleans as numbers.
Characters and bytes
String length counts code points, not necessarily displayed symbols or encoded bytes:
print(len("café"), len("café".encode("utf-8"))) # 4 5
print(len("e\u0301")) # 2: e + combining accentA display limit and a network byte limit need different policies. encode() produces bytes without changing the original text.
Repeated concatenation of growing strings can require repeated allocation and copying. When pieces are already available, join() is often clearer and avoids repeatedly rebuilding the prefix.
Put it into practice
Implement the exercise in a full-screen workspace, then run its tests.