Skip to content

Comparing Variable Types Across Python, NumPy, and Pandas

By this point in the course, you've met a fairly wide cast of variable types, starting with the humble integer and float, moving through strings, lists and dictionaries, then NumPy arrays, and finally pandas Series and DataFrames. It's easy, at this stage, to experience these as a long, unconnected list of things to memorise. In reality, they form a fairly natural progression, and seeing them laid out side by side, rather than encountered one at a time across separate sessions, often makes the relationships between them click in a way that reading about them individually doesn't.

The table below is designed to be a reference you return to, not something to memorise in one sitting. Use it whenever you find yourself unsure which type is the right tool for a particular job, or when you're trying to recall exactly how one type differs from something that feels superficially similar (a list versus a tuple, say, or a NumPy array versus a plain Python list).

A few dimensions are worth paying close attention to as you read across the rows:

Ordering matters because it determines whether "the second item" is even a meaningful question to ask. Lists, tuples, strings, arrays, and DataFrames all have a well-defined order, you can always ask for the third element and get a sensible answer. Dictionaries technically preserve insertion order in modern Python, but you'd rarely rely on that order for anything meaningful, since you look things up by key, not position. Sets abandon ordering entirely, trading it for very fast membership checks ("is this value already in here?").

Mutability, whether a type can be changed after it's created, is one of the more subtle distinctions, and one that causes real bugs when overlooked. Strings and tuples are immutable: once created, any "change" actually produces a brand new object rather than modifying the original in place. This is why string methods like .upper() return a new string rather than altering the original. Lists, dictionaries, arrays, and DataFrames, by contrast, can be modified directly, which is powerful, but also means you need to be careful about accidentally modifying shared data, exactly the kind of "slices are views, not copies" behaviour we saw earlier with NumPy arrays.

Dimensionality is where the progression becomes especially visible. Single values like int and float are zero-dimensional, they're just one number. Lists and strings are one-dimensional, a single ordered row of values. NumPy arrays generalise this idea further, supporting not just 1D but 2D matrices and even higher-dimensional structures, which is precisely what makes them so well suited to things like images, time series, or simulation output. Pandas then takes the 2D case, arguably the single most common shape of real-world data, tables, spreadsheets, CSV files and gives it an extra layer of structure: labelled rows and columns, rather than just raw numerical position.

Type flexibility is another axis worth noticing. A Python list or dictionary can happily mix an integer, a string, and a float in the same collection, this flexibility is convenient but comes at a performance cost. NumPy trades that flexibility away deliberately: every element in an array shares the same dtype, which is exactly what allows NumPy to perform calculations so much faster than equivalent Python loops. Pandas then strikes a kind of middle ground: within a single column (a Series), every value shares one dtype, just like a NumPy array, but across an entire DataFrame, different columns are free to hold entirely different types side by side, numbers in one column, text in another, dates in a third, which is exactly what real datasets tend to need.

Perhaps the most useful way to internalise this table isn't to treat each row as an isolated fact, but to notice the throughline connecting them. A pandas DataFrame isn't a totally new invention arriving out of nowhere in Session 2, it's built directly on ideas you already know: it's a table made of columns, each column behaves like a labelled NumPy array (a Series), and a NumPy array itself behaves like a faster, stricter version of a Python list. Once that chain feels intuitive, decisions about which type to reach for in your own code become much less about memorising rules, and much more about simply asking: "is this a single value, an unordered bag, an ordered sequence, a numerical grid, or a full table?", and letting the answer point you to the right tool.

Type Library Stores Ordered? Mutable? Dimensions Mixed types allowed? Typical use
int Core Python A single whole number N/A (single value) No (a new int is created on change) 0D (scalar) N/A Counting, indexing, whole-number arithmetic
float Core Python A single decimal number N/A (single value) No 0D (scalar) N/A Measurements, calculations needing precision
bool Core Python A single True/False value N/A (single value) No 0D (scalar) N/A Conditions, flags, filters
str Core Python A sequence of characters Yes No (immutable) 1D No, characters only Text, labels, messages
list Core Python An ordered collection of values Yes Yes 1D (can nest for more) Yes General-purpose ordered collections
tuple Core Python An ordered, fixed collection of values Yes No (immutable) 1D Yes Fixed groupings of values that shouldn't change
dict Core Python Key-value pairs Insertion order preserved (3.7+) Yes N/A (mapping, not positional) Yes (keys and values) Structured lookup by label
set Core Python An unordered collection of unique values No Yes 1D Yes Removing duplicates, membership testing
np.ndarray NumPy A grid of numerical (or fixed-type) values Yes Yes 1D, 2D, or N-D No, single fixed dtype per array Fast numerical computation across large datasets
np.dtype NumPy Describes the data type stored in an array (e.g. int64, float64) N/A N/A N/A N/A Controls memory usage and precision of array contents
pd.Series Pandas A single labelled, one-dimensional column of data Yes (with an index) Yes 1D No, one dtype per Series (like an ndarray) A single labelled column, or one row/column from a DataFrame
pd.DataFrame Pandas A labelled, two-dimensional table of data Yes (rows and columns both labelled) Yes 2D Yes, each column can have its own dtype Spreadsheet-like structured, tabular data
pd.Index Pandas The labels used to identify rows (or columns) Yes No (typically immutable) 1D Usually no, one dtype per Index Labelling and aligning rows/columns in a Series or DataFrame