Ch 2.2 Basic Data Types
Python's basic data types are integers (int), floating-point numbers (float), booleans (bool), strings (str), and None. This chapter explores the characteristics of each type and points to watch out for in real-world use.
1. int — Integers
Python integers support arbitrary precision. Unlike other languages, there is no integer overflow.
# Basic integers
x = 42
y = -100
z = 0
# Large integers work just fine
big_number = 10 ** 100 # Googol — no overflow
print(big_number)
# 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
# Different bases
binary = 0b1010 # Binary (10)
octal = 0o17 # Octal (15)
hexadecimal = 0xFF # Hexadecimal (255)
print(binary, octal, hexadecimal) # 10 15 255
# Underscore separator for readability (Python 3.6+)
million = 1_000_000
billion = 1_000_000_000
hex_color = 0xFF_A5_00 # Orange #FFA500
print(million) # 1000000
print(billion) # 1000000000
Built-in Functions for Integers
# abs() — absolute value
print(abs(-42)) # 42
print(abs(42)) # 42
# divmod() — returns quotient and remainder as a tuple
quotient, remainder = divmod(17, 5)
print(quotient, remainder) # 3 2
# pow() — exponentiation (third argument enables modular exponentiation)
print(pow(2, 10)) # 1024
print(pow(2, 10, 100)) # 1024 % 100 = 24 (useful in cryptography)
# round() — rounding
print(round(3.7)) # 4
print(round(3.14159, 2)) # 3.14
# bin(), oct(), hex() — base conversion
print(bin(255)) # '0b11111111'
print(oct(255)) # '0o377'
print(hex(255)) # '0xff'
2. float — Floating-Point Numbers
# Basic floats
x = 3.14
y = -2.71828
z = 1.0
# Scientific notation
speed_of_light = 3e8 # 3 × 10^8 = 300000000.0
electron_mass = 9.109e-31 # 9.109 × 10^-31
print(speed_of_light) # 300000000.0
Floating-Point Precision Issues
# 0.1 + 0.2 is not 0.3!
result = 0.1 + 0.2
print(result) # 0.30000000000000004
print(result == 0.3) # False !!
# Reason: computers represent decimals in binary, so the result is an approximation
# Solution 1: use round() (for simple cases)
print(round(0.1 + 0.2, 1)) # 0.3
print(round(0.1 + 0.2, 10) == 0.3) # True
# Solution 2: use math.isclose() (for comparisons)
import math
print(math.isclose(0.1 + 0.2, 0.3)) # True
# Solution 3: use decimal.Decimal (for financial/precision calculations)
from decimal import Decimal
a = Decimal("0.1")
b = Decimal("0.2")
print(a + b) # 0.3 (exact!)
print(a + b == Decimal("0.3")) # True
# Financial calculation example
price = Decimal("29900")
discount = Decimal("0.1")
final_price = price * (1 - discount)
print(final_price) # 26910.0
3. bool — Booleans
Python's bool is a subclass of int. True is treated as 1 and False as 0.
# Basic booleans
is_active = True
is_deleted = False
print(type(True)) # <class 'bool'>
print(isinstance(True, int)) # True — bool is a subclass of int!
# bool can be used in arithmetic
print(True + True) # 2
print(True * 10) # 10
print(False + 1) # 1
# Practical use: counting True values in a list
scores = [85, 92, 78, 55, 90, 45]
passed = [score >= 60 for score in scores]
print(passed) # [True, True, True, False, True, False]
print(sum(passed)) # 4 (number of passing scores)
# Comparison operators return bool
print(10 > 5) # True
print(10 == "10") # False
print(type(10 > 5)) # <class 'bool'>
4. str — Strings
Strings are immutable sequences. Once created, a string cannot be changed.
# Various quoting styles
single = 'single quotes'
double = "double quotes"
triple_single = '''three-line
string
works fine'''
triple_double = """multi-line
string"""
# Escape characters
newline = "First line\nSecond line"
tab = "Name:\tAlice"
backslash = "Path: C:\\Users\\alice"
quote = 'He said: "Hello"'
print(newline)
print(tab)
# Raw string — no escape processing (useful for regex and paths)
path = r"C:\Users\alice\Documents"
regex = r"\d+\.\d+"
print(path) # C:\Users\alice\Documents (backslashes preserved)
# String indexing and slicing
text = "Python"
print(text[0]) # P
print(text[-1]) # n
print(text[1:4]) # yth
print(text[::-1]) # nohtyP (reversed)
# Confirming immutability
# text[0] = "J" # TypeError: 'str' object does not support item assignment
# Since strings are immutable, create a new one
text = "J" + text[1:]
print(text) # Jython
5. NoneType — None
None is a special object in Python that represents the absence of a value. It is equivalent to null in other languages.
# Assigning None
result = None
user = None
# Checking for None — using `is` is the recommended approach
if result is None:
print("No result.")
if user is not None:
print(f"User: {user}")
# Difference between == and is
print(None == None) # True
print(None is None) # True (this is recommended)
# None is the default return value of a function
def do_nothing():
pass # A function without return returns None
result = do_nothing()
print(result) # None
print(type(result)) # <class 'NoneType'>
# None is a falsy value
print(bool(None)) # False
if not None:
print("None evaluates to False.")
# Commonly used as a function parameter default
def greet(name=None):
if name is None:
return "Hello, stranger!"
return f"Hello, {name}!"
print(greet()) # Hello, stranger!
print(greet("Alice")) # Hello, Alice!
6. Using type() and isinstance()
# type() — returns the exact type
x = 42
print(type(x)) # <class 'int'>
print(type(x) == int) # True
print(type(x) == str) # False
# isinstance() — checks type considering inheritance (recommended)
print(isinstance(x, int)) # True
print(isinstance(True, int)) # True — bool is a subclass of int
print(isinstance(True, bool)) # True
# Checking multiple types at once
def process(value):
if isinstance(value, (int, float)):
return value * 2
elif isinstance(value, str):
return value.upper()
else:
raise TypeError(f"Unsupported type: {type(value)}")
print(process(5)) # 10
print(process(3.14)) # 6.28
print(process("hello")) # HELLO
Pro Tips:
sys.maxsize, math.inf, and math.nanimport sys
import math
# sys.maxsize — maximum index size for lists/strings on the current platform
print(sys.maxsize) # 9223372036854775807 (64-bit system)
# Python integers have no practical limit
huge = sys.maxsize + 1 # No overflow
print(type(huge)) # <class 'int'>
# math.inf — positive infinity
positive_inf = math.inf
negative_inf = -math.inf
print(math.inf > 10**1000) # True
# float('inf') is the same
print(float('inf') == math.inf) # True
# Common pattern: initialize minimum with infinity
def find_min(numbers):
minimum = math.inf
for num in numbers:
if num < minimum:
minimum = num
return minimum
print(find_min([5, 3, 8, 1, 9])) # 1
# math.nan — Not a Number
nan = math.nan
print(nan) # nan
print(nan == nan) # False!! (NaN is not equal to itself)
print(math.isnan(nan)) # True (use isnan to check for nan)
# Practical use: representing missing data
data = [1.0, 2.0, math.nan, 4.0, math.nan, 6.0]
valid_data = [x for x in data if not math.isnan(x)]
print(valid_data) # [1.0, 2.0, 4.0, 6.0]
You have mastered the basic data types. The next chapter takes a deep look at Python's powerful collection types: list, tuple, set, and dict.