How to store a variable in Python

Learn how you can store variables in Python. This guide covers methods, tips, real-world applications, and debugging common errors.

How to store a variable in Python
Published on: 
Tue
Mar 17, 2026
Updated on: 
Fri
Mar 20, 2026
The Replit Team

Storing variables is a core concept in Python. It lets you label and hold data for later use with the = operator. This fundamental skill is essential for any developer.

Here, you'll learn techniques to store variables, from basic assignment to advanced methods. You'll also find practical tips, real-world applications, and advice to debug common issues effectively.

Basic variable assignment

name = "John"
age = 30
print(name, "is", age, "years old")--OUTPUT--John is 30 years old

This example uses the = operator to assign values to variables. The key takeaway isn't just the assignment itself but the clarity it brings. By using descriptive names like name and age, the code becomes self-documenting and easier to understand at a glance.

  • Python's dynamic typing is on display here. You don't need to declare a variable's type; the interpreter infers it automatically when you assign a value.
  • This approach makes your code more flexible and often faster to write.

Common variable techniques

Building on the simple = operator, Python offers more sophisticated techniques for handling different data types and assigning multiple variables at once.

Working with different data types

integer_var = 42
float_var = 3.14
string_var = "Hello"
boolean_var = True
print(f"Types: {type(integer_var)}, {type(float_var)}, {type(string_var)}, {type(boolean_var)}")--OUTPUT--Types: <class 'int'>, <class 'float'>, <class 'str'>, <class 'bool'>

Python handles various data types, from numbers to text, without needing you to declare them first. The example demonstrates four common types: integers (int), floating-point numbers (float), strings (str), and booleans (bool). Python automatically infers the correct type based on the value assigned.

  • You can always check a variable's type using the built-in type() function. This is especially useful for debugging or when you're working with data from an unknown source.

Assigning multiple variables at once

x, y, z = 10, 20, 30
a = b = c = 100
print(f"x: {x}, y: {y}, z: {z}")
print(f"a: {a}, b: {b}, c: {c}")--OUTPUT--x: 10, y: 20, z: 30
a: 100, b: 100, c: 100

Python offers shortcuts for assigning variables to make your code cleaner. For instance, x, y, z = 10, 20, 30 unpacks the sequence of numbers, assigning 10 to x, 20 to y, and so on. It's a concise way to initialize several variables with distinct values.

  • For assigning the same value, you can chain them together. The line a = b = c = 100 sets all three variables to 100 simultaneously.

Using unpacking for variable assignment

values = [1, 2, 3]
first, second, third = values
coordinates = (10.5, 20.7)
x, y = coordinates
print(f"Unpacked list: {first}, {second}, {third}")
print(f"Unpacked tuple: x={x}, y={y}")--OUTPUT--Unpacked list: 1, 2, 3
Unpacked tuple: x=10.5, y=20.7

Unpacking lets you assign elements from a sequence, such as a list or tuple, directly to variables. As shown with the values list, each item is mapped to a corresponding variable. This makes your code more readable by giving meaningful names to individual elements.

  • This technique works with any iterable, including lists and tuples like coordinates.
  • The number of variables must exactly match the number of items in the sequence, or you'll get an error.

Advanced variable storage

As you build more complex programs, you'll find that managing variables effectively requires more than just basic assignment—it involves strategies for clarity and introspection.

Using variable annotations with typing

from typing import List, Dict, Tuple

names: List[str] = ["Alice", "Bob", "Charlie"]
scores: Dict[str, int] = {"Alice": 95, "Bob": 87}
point: Tuple[float, float] = (3.5, 7.2)
print(f"First name: {names[0]}, Bob's score: {scores['Bob']}")--OUTPUT--First name: Alice, Bob's score: 87

Variable annotations are like adding labels to your variables to clarify their expected data type. Using the typing module, you can specify complex types like List[str] for a list of strings. While these hints don't change how your code runs—Python still infers types dynamically—they make your intentions clear to other developers and static analysis tools.

  • The annotation scores: Dict[str, int] signals that scores is a dictionary with string keys and integer values.
  • Similarly, point: Tuple[float, float] indicates a tuple containing exactly two floating-point numbers, improving code predictability.

Working with constants and naming conventions

PI = 3.14159
MAX_CONNECTIONS = 100
user_name = "john_doe"  # Snake case for variables
UserPreferences = {"theme": "dark", "notifications": True}  # Pascal case for classes
print(f"Area of circle: {PI * 5 * 5}, Max connections: {MAX_CONNECTIONS}")--OUTPUT--Area of circle: 78.53975, Max connections: 100

While Python doesn't have true constants, the convention is to use all-caps names like PI and MAX_CONNECTIONS to signal that a value shouldn't change. It's a community agreement that helps keep code predictable and maintainable.

  • For regular variables, use snake_case, where words are separated by underscores, as seen in user_name.
  • For classes, the standard is PascalCase, where each word is capitalized. This convention helps distinguish classes from other objects at a glance.

Using the vars() and globals() functions

x = 10
y = "Hello"

# View all local variables
local_vars = vars()
print(f"Local variables: {list(local_vars.keys())[:4]}")

# Access global variables
print(f"Value of x from globals: {globals()['x']}")--OUTPUT--Local variables: ['__name__', '__doc__', '__package__', '__loader__']
Value of x from globals: 10

Python gives you tools for introspection, letting you examine your program's state as it runs. The vars() and globals() functions return dictionaries containing the variables in the current local and global scopes, respectively. This is powerful for debugging or dynamically accessing variables by name.

  • The globals() function provides a dictionary of all variables in the global scope. You can then access a variable's value using its name as a key, like globals()['x'].
  • When called without arguments, vars() behaves like locals(), showing you what's defined in the current scope.

Move faster with Replit

Replit is an AI-powered development platform that transforms natural language into working applications. You can describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.

The variable storage techniques we've covered can be turned into production-ready tools with Replit Agent. For example, it can build complete applications from these concepts.

  • Build a user profile system that stores name, age, and other details using basic variable assignment.
  • Create a configuration manager for an application that handles constants like MAX_CONNECTIONS and follows standard naming conventions.
  • Deploy a data processing utility that unpacks coordinates from datasets to visualize geographical information.

Describe your app idea, and Replit Agent will write the code, test it, and fix issues automatically, all in your browser.

Common errors and challenges

Even with the basics down, you might run into a few common roadblocks, from unpacking errors to unexpected behavior with mutable types.

Unpacking requires the number of variables to exactly match the number of items in a sequence. When they don't, Python raises a ValueError. To fix this, you can use the asterisk * operator to capture a variable number of items. For instance, in an assignment like first, *rest = [1, 2, 3], the *rest variable flexibly collects all remaining items into a list, which in this case would be [2, 3].

A NameError is another frequent hurdle, which occurs when you try to use a variable that hasn't been assigned a value yet. It's usually caused by a simple typo or by calling the variable before it's defined in your code's execution flow.

  • To debug it, first check for spelling mistakes in your variable name.
  • If the name is correct, confirm that the assignment statement runs before the variable is accessed.

A more subtle issue arises with mutable default arguments in functions, such as using an empty list []. Python creates this default object only once, so any modifications made to it during a function call will persist across all subsequent calls. This can lead to unexpected shared state.

  • The best practice is to use None as the default value.
  • Inside the function, you can then check if the argument is None and create a new list or dictionary. This ensures each call operates on a fresh, independent object.

Fixing unbalanced unpacking errors with the * operator

Unpacking works beautifully when your variables and values are perfectly aligned. But what happens when you have more values than variables? Python raises a ValueError, a common error when the number of items to unpack doesn't match. The code below shows this in action.

values = [1, 2, 3, 4, 5]
a, b, c = values  # This will raise ValueError: too many values to unpack
print(f"a: {a}, b: {b}, c: {c}")

Here, the values list holds five items, but the assignment a, b, c = values only provides three variables. This mismatch is what triggers the error. The following example shows how to fix this.

values = [1, 2, 3, 4, 5]
a, b, *rest = values  # Use * to collect remaining values
print(f"a: {a}, b: {b}, rest: {rest}")

The fix is to use the asterisk operator (*), which tells Python to collect any leftover items into a list. In the assignment a, b, *rest = values, the *rest variable scoops up all values after a and b are assigned.

  • This technique is especially handy when you're working with data of unpredictable length, such as function arguments or API responses, where you only need to process the first few elements.

Debugging NameError when using variables before assignment

A NameError is one of the most common issues you'll face. It happens when you try to use a variable that hasn't been defined yet. This often comes down to a simple typo or calling a variable out of sequence.

The code below demonstrates this error inside the calculate_total() function, where subtotal is used before it's assigned a value.

def calculate_total():
   tax_rate = 0.08
   total = subtotal + (subtotal * tax_rate)  # NameError: name 'subtotal' is not defined
   return total

print(calculate_total())

The calculate_total() function fails because it tries to read from subtotal to perform a calculation. Since subtotal has no value assigned within the function's scope, Python can't proceed. The corrected code shows how to resolve this.

def calculate_total(subtotal):
   tax_rate = 0.08
   total = subtotal + (subtotal * tax_rate)
   return total

print(calculate_total(100))

The fix is to pass subtotal as an argument to the calculate_total() function. This makes the value available inside the function's local scope, resolving the NameError. It's a straightforward solution that ensures the function has all the data it needs to run.

  • Keep an eye out for this error when a variable is used inside a function but defined outside of it, or not at all.

Avoiding mutable default value issues

A common pitfall in Python is using a mutable type, like a list, as a default function argument. Because the default object is created only once, it's shared across every call, leading to surprising side effects. The following code demonstrates this behavior.

def add_item(item, shopping_list=[]):
   shopping_list.append(item)
   return shopping_list

print(add_item("Apple"))  # ['Apple']
print(add_item("Banana"))  # Unexpected: ['Apple', 'Banana']

The add_item function reuses the same default [] list across all calls. The second call appends "Banana" to the list that already holds "Apple" from the first run, creating an unintended shared state. The corrected code below shows how to fix this.

def add_item(item, shopping_list=None):
   if shopping_list is None:
       shopping_list = []
   shopping_list.append(item)
   return shopping_list

print(add_item("Apple"))  # ['Apple']
print(add_item("Banana"))  # ['Banana']

The corrected code solves the issue by setting the default argument to None. Inside the add_item function, it checks if the list is None and, if so, creates a new empty list []. This ensures each function call gets a fresh, independent list, preventing the shared state that caused the unexpected behavior.

  • It's a good habit to use this pattern whenever a function's default argument is a mutable type like a list or dict.

Real-world applications

Beyond debugging errors, these variable storage methods are essential for practical applications, from managing a personal budget to performing currency conversions.

Managing a budget with variable assignment

Variable assignment is perfect for building a simple budget tracker, where you can define income and subtract expenses to calculate your savings.

income = 5000
rent, utilities, groceries = 1500, 200, 400
savings = income - (rent + utilities + groceries)
print(f"Income: ${income}, Expenses: ${rent + utilities + groceries}, Savings: ${savings}")

This snippet showcases how to manage related data cleanly. By using tuple unpacking, you can initialize rent, utilities, and groceries in a single, readable line. It's more efficient than writing three separate assignments.

  • The calculation for savings is self-documenting because it uses descriptive variable names, making the logic clear at a glance.
  • The final print() function leverages an f-string to embed expressions—like the sum of expenses—directly into the output for a concise and dynamic message.

Currency conversion with multiple variable assignment

You can also use multiple variable assignment to handle calculations like currency conversions, assigning several results to their respective variables all at once.

exchange_rates = {"USD": 1.0, "EUR": 0.85, "GBP": 0.75, "JPY": 110.2}
amount = 100
currency = "USD"

# Convert to all other currencies
usd, eur, gbp, jpy = amount, amount * exchange_rates["EUR"], amount * exchange_rates["GBP"], amount * exchange_rates["JPY"]
print(f"{amount} {currency} equals: {eur:.2f} EUR, {gbp:.2f} GBP, {jpy:.2f} JPY")

This code uses a dictionary of exchange rates to convert a base currency amount into several others simultaneously. The exchange_rates dictionary neatly stores the conversion factors, which are then used in calculations.

  • The key technique is assigning multiple variables in one statement. All calculations, such as amount * exchange_rates["EUR"], are evaluated first.
  • Python then assigns each result to its corresponding variable—usd, eur, gbp, and jpy—in a single, clean operation.

Get started with Replit

Turn these concepts into a real tool. Tell Replit Agent: “Build a currency converter using a dictionary for rates” or “Create a budget tracker that unpacks expenses to calculate savings.”

Replit Agent writes the code, tests for errors, and deploys your application. It handles the entire development cycle for you. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.