Skip to main content
Advertisement

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.nan
import 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.

Advertisement