Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Python›Variables and Data Types

Foundations

Variables and Data Types

This lesson explores how data is stored, categorized, and manipulated within memory during program execution. Understanding these foundational types is essential for managing state and ensuring logical operations perform as expected across complex systems. You will reach for these concepts whenever you need to represent real-world information, such as user identities, numerical metrics, or structured sequences, in your codebase.

The Mechanism of Variable Assignment

In this environment, a variable is not a container that holds a value, but rather a symbolic name that acts as a reference or a pointer to an object stored somewhere in memory. When you perform an assignment, you are binding a label to an object, not copying data into a fixed location. This distinction is critical because it explains why multiple variables can refer to the same object simultaneously. When you reassign a variable, the label is simply pointed toward a new object, leaving the previous object to be managed by the memory cleanup system. Understanding this reference-based model allows you to reason about how data behaves when passed to functions or reassigned within loops, preventing common pitfalls related to object identity and mutation. This abstraction ensures that variables are dynamic and lightweight, facilitating efficient memory management while providing flexibility for the developer to define relationships between data points dynamically as the program state evolves throughout its execution lifecycle.

# Assigning an integer object to a label
user_count = 42

# Creating a new label referencing the same object
current_users = user_count

# Reassigning the label to a different object
user_count = 43

# current_users still references the original object 42
print(f"User count: {user_count}, Current users: {current_users}")

Numerical Data Types: Integers and Floats

Numbers are fundamental to nearly every computational task, and they are categorized based on their precision and mathematical properties. Integers represent whole numbers without fractional components, and they are unique because they have arbitrary precision, meaning they can grow as large as your system memory allows without overflowing. This makes them robust for counting or indexing where exactness is required. On the other hand, floating-point numbers represent real numbers with fractional parts, using a standard binary approximation system. This approximation means that calculations with floats can sometimes lead to tiny, precision-based errors that you must account for when comparing values. When you perform operations between integers and floats, the system promotes the integer to a float to ensure consistency. Understanding this hierarchy of numerical representation helps you choose the correct type for your logic, ensuring that high-precision mathematical operations remain accurate and that memory usage is optimized for the scale of the calculations being performed within your algorithmic components.

# Integer for exact counts
active_tasks = 150

# Float for precise measurements
process_latency = 0.0035

# Mixed operations result in a float
load_factor = active_tasks * process_latency
print(f"The load factor is: {load_factor}")

String Representation and Immutability

Strings are sequences of characters used to represent textual information. A core characteristic of strings is that they are immutable, which means once they are created, their contents cannot be modified in place. When you perform operations such as concatenation or slicing, you are actually constructing entirely new string objects rather than altering the original one. This design choice provides a significant security and performance benefit, as it ensures that shared string references remain consistent and stable throughout the execution of a function. Furthermore, strings are sequence types that support indexing, allowing you to access individual characters or sub-sequences efficiently. Because they are objects, they come equipped with built-in methods for manipulation, such as changing case, splitting, or formatting. Recognizing that strings are immutable forces you to be deliberate about how you process large amounts of text, encouraging the use of efficient construction patterns when building dynamic output to avoid unnecessary memory overhead from creating too many intermediate string objects.

# Strings are immutable sequences
username = "admin_user"

# Concatenation creates a new object in memory
formatted_name = username.upper() + "_PRO"

# Original string remains unchanged
print(f"Original: {username}, New: {formatted_name}")

Boolean Logic and Truthiness

Boolean values represent the two possible states of logical truth: true or false. These values are the bedrock of control flow, powering conditional statements that dictate the path of your code based on runtime outcomes. What makes this system particularly flexible is the concept of 'truthiness,' where most data objects can be evaluated in a logical context. For instance, an empty sequence or a zero value evaluates to false, while populated structures or non-zero numbers evaluate to true. This allows you to write clean, concise conditional logic without explicitly checking for every possible null or empty condition. By relying on these evaluation rules, you make your code more readable and idiomatic, as the structure inherently understands what constitutes a valid or meaningful state. Mastering boolean logic involves not just using comparison operators, but also understanding how different data structures interact with logical operators to create efficient, branch-based decision trees that respond dynamically to incoming data inputs during the program runtime.

# Booleans represent binary states
is_authenticated = True
retry_allowed = False

# Evaluating truthiness in conditionals
if is_authenticated and not retry_allowed:
    print("Access granted to the secure module.")

Managing Complex Collections: Lists

Lists represent ordered, mutable collections of objects, providing a way to store sequences of related data in a single variable. Because lists are mutable, you can add, remove, or change elements after the list has been created, making them an ideal structure for data that changes during execution. Each element in a list is stored as a reference to an object, allowing a single list to hold mixed data types simultaneously, such as a combination of integers, strings, or even other lists. This flexibility makes lists highly versatile for representing queues, stacks, or dynamic arrays. When you work with lists, it is crucial to remember that modifying a list via a reference in one part of your code affects all other parts referencing that same list object. This behavior necessitates a deep understanding of reference management, especially when duplicating collections or passing them between different functions, to avoid accidental side effects during complex data transformations or iterative processing tasks within your applications.

# A list storing mixed types
server_metrics = [120, "active", 98.5]

# Adding a new element to the list (mutation)
server_metrics.append("verified")

# Accessing elements via index
print(f"Metric status: {server_metrics[1]}")

Key points

  • Variables act as labels that point to objects in memory rather than acting as fixed storage containers.
  • Integers provide arbitrary precision for exact counts, while floats are used for fractional numerical representations.
  • Strings are immutable, meaning any modification results in the creation of an entirely new string object.
  • Truthiness allows objects like empty lists or zero to be treated as False in logical conditional statements.
  • Lists are mutable, allowing for dynamic additions and removals of elements throughout the execution of a program.
  • Reassigning a variable updates the label to point to a different object instead of changing the original data.
  • Mixed data types can exist within a single collection like a list, providing significant flexibility for data modeling.
  • Understanding reference behavior is essential to avoid unintended side effects when multiple labels point to the same object.

Common mistakes

  • Mistake: Using a keyword as a variable name. Why it's wrong: Keywords like 'class' or 'def' are reserved for Python syntax. Fix: Use descriptive names like 'user_class' or 'define_function'.
  • Mistake: Confusing integer division with float division. Why it's wrong: Using '/' always results in a float, while '//' performs floor division. Fix: Use '//' if you need an integer result.
  • Mistake: Trying to modify a string directly by index. Why it's wrong: Strings in Python are immutable and cannot be changed in place. Fix: Create a new string using concatenation or slicing.
  • Mistake: Expecting input() to return an integer. Why it's wrong: The input() function always returns a string. Fix: Wrap the input function in int() or float() to convert the data type.
  • Mistake: Assuming variables retain their type permanently. Why it's wrong: Python is dynamically typed, meaning a variable can be reassigned to a different data type. Fix: Be mindful of reassignment and use type hinting if strictness is required.

Interview questions

What is a variable in Python, and how do you create one?

In Python, a variable is essentially a reserved memory location used to store values, acting as a label or a reference to an object. You create one through simple assignment using the equals operator. For example, writing 'age = 25' binds the integer 25 to the name 'age'. This is dynamic, meaning Python automatically determines the data type based on the value, making it very flexible for developers.

What are the core primitive data types available in Python?

Python provides several fundamental data types to handle different kinds of information. These include 'int' for whole numbers like 10, 'float' for decimal numbers like 3.14, 'str' for textual data enclosed in quotes like 'hello', and 'bool' for truth values, represented as True or False. Understanding these is crucial because Python uses these types to determine which operations can be performed on the data, such as arithmetic for numbers or concatenation for strings.

What is the difference between a list and a tuple in Python?

The primary difference lies in mutability. A list is defined using square brackets, like 'my_list = [1, 2, 3]', and its contents can be modified, added, or removed after creation. In contrast, a tuple is defined with parentheses, like 'my_tuple = (1, 2, 3)', and is immutable, meaning it cannot be changed once defined. You should use lists for collections of items that may evolve, while tuples are ideal for fixed data structures where integrity must be preserved.

Can you explain the difference between a list and a set, and when you would choose one over the other?

The difference is fundamental to how data is accessed and stored. A list is an ordered collection that allows duplicate elements, making it ideal for sequences where order matters. A set, however, is an unordered collection of unique elements. You should choose a set when you need to perform membership testing quickly or when you explicitly need to ensure that no duplicate values exist within your dataset, as sets are optimized for these scenarios.

How does Python handle dynamic typing, and why is this advantageous?

Dynamic typing means that the data type of a variable is determined at runtime rather than being explicitly declared during compilation. For example, you can assign 'x = 10' and later 'x = "text"' without error. This is advantageous because it allows for rapid prototyping and more concise code, reducing boilerplate. However, it places the responsibility on the developer to track variable states to avoid runtime errors, requiring robust testing practices.

Compare using a dictionary versus a list of tuples for storing key-value pairs; which approach is more efficient?

Using a dictionary is significantly more efficient for retrieving data by key because dictionaries are implemented as hash tables in Python. Accessing a value via a key, such as 'data["name"]', happens in constant time, O(1). Conversely, searching for a key in a list of tuples requires iterating through the list, which results in linear time complexity, O(n). Therefore, dictionaries are the preferred choice whenever you need fast, indexed lookups for your data.

All Python interview questions →

Check yourself

1. What is the output of print(type(1 / 2))?

  • A.<class 'int'>
  • B.<class 'float'>
  • C.<class 'decimal'>
  • D.Error
Show answer

B. <class 'float'>
In Python 3, the single forward slash operator performs float division, even if both numbers are integers. Options 0 and 2 are incorrect because the result is a float, and option 3 is wrong because this is valid syntax.

2. Which of the following variable assignments will raise a SyntaxError?

  • A.my_var = 10
  • B.2nd_value = 20
  • C._total = 100
  • D.dataValue = 'test'
Show answer

B. 2nd_value = 20
Variable names cannot start with a number in Python. All other options are valid variable identifiers. Option 0, 2, and 3 are correct naming conventions.

3. If x = '5', what is the result of x + 5?

  • A.10
  • B.55
  • C.TypeError
  • D.None
Show answer

C. TypeError
Python does not allow implicit type conversion between strings and integers during addition. Option 0 and 1 are incorrect because they assume string conversion or integer math occurs automatically. Option 3 is wrong because an exception is raised.

4. Which statement best describes the mutability of a Python tuple?

  • A.Tuples are mutable and can be changed after creation.
  • B.Tuples are immutable and cannot be changed after creation.
  • C.Tuples only become immutable when they contain only integers.
  • D.Tuples can only be changed if they have more than one element.
Show answer

B. Tuples are immutable and cannot be changed after creation.
Tuples are defined as immutable sequences. Once created, their elements cannot be modified, added, or removed. Options 0, 2, and 3 are incorrect because mutability is a property of the data type itself, not dependent on content or size.

5. What is the result of print(bool('False'))?

  • A.False
  • B.True
  • C.0
  • D.TypeError
Show answer

B. True
The bool() function returns True for any non-empty string, regardless of the text contained within it. Therefore, 'False' as a string is truthy. Options 0, 2, and 3 are incorrect because they misunderstand the truthiness of non-empty strings.

Take the full Python quiz →

← PreviousIntroduction to PythonNext →Operators (Arithmetic, Comparison, Logical)

Python

78 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app