Efficient way to store millions of arrays, and perform IN check
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
Introduction
If you need to store millions of arrays and perform exact membership checks, the best representation depends on what "IN check" really means. For exact whole-array lookup, the usual strategy is to convert each array into a canonical hashable form and store those keys in a hash set or database index, instead of scanning millions of arrays linearly every time.
Define the Lookup Problem First
There are at least three different questions that sound like "is this array in the collection":
- exact whole-array membership
- element membership inside any stored array
- prefix, range, or approximate similarity lookup
Those problems need different data structures. This article focuses on exact whole-array membership, because that is the case where IN-style lookup is most naturally answered with a canonical key and a hash-based index.
If you only need exact matches, a full table scan is almost never the right answer once the dataset reaches millions of arrays.
Use a Canonical Key for Exact Membership
For Python data, a tuple is often the simplest canonical form:
This turns membership checking from linear search into average-case constant-time hash lookup.
That approach works well when:
- arrays are short
- elements are hashable
- exact order matters
It is much more efficient than repeatedly comparing the candidate against every stored array in a list.
Use Compact Binary Keys for Large Numeric Arrays
If the arrays are numeric and all share the same dtype and shape, using a compact binary representation can be more memory-efficient than storing large Python tuples.
For example with NumPy:
This is fast and compact, but only if you control shape and dtype carefully. The bytes for int32 and int64 representations of the same values are not interchangeable.
A safer production key often includes metadata:
That avoids false matches between arrays that happen to serialize to ambiguous byte patterns under different assumptions.
Think About Storage Layout, Not Only Lookup
If you need both efficient storage and efficient membership, separate the concerns:
- store the raw arrays in a compact numeric format
- store a hash or canonical key for fast lookup
For example, in a database table you might keep:
- an integer primary key
- the array payload
- a unique hash column computed from canonicalized array contents
Then the membership test becomes an indexed lookup on the hash rather than a scan over the payload column.
This is the same principle as the in-memory set example, just moved into persistent storage.
If arrays are extremely large or highly repetitive, deduplication and compression can also matter more than the membership algorithm itself.
Use Tries or Inverted Indexes Only for Different Query Types
A trie or inverted index can be excellent, but only if the query type justifies it. For example:
- a trie helps with prefix-based lookup
- an inverted index helps find arrays containing a specific element
- locality-sensitive hashing helps approximate nearest-neighbor search
Those are powerful structures, but they are not the first answer for exact whole-array membership. For exact equality, a canonical key plus a hash table is usually the simplest and fastest design.
The most expensive mistake is solving a different problem than the one you actually have.
Common Pitfalls
The biggest mistake is storing millions of arrays as nested Python lists and using candidate in arrays for repeated checks. That forces linear scans and scales poorly.
Another issue is choosing a binary representation without fixing dtype and shape. Two arrays that look similar at a high level can serialize differently, and two byte strings that match may be meaningless if metadata is ignored.
Developers also sometimes overengineer the problem with tries, bloom filters, or distributed systems before proving that a simple canonical-key hash index is insufficient.
Finally, remember that exact membership and approximate similarity are different use cases. A structure optimized for one will often be wrong for the other.
Summary
- For exact whole-array membership, convert each array into a canonical hashable key and index those keys.
- Python tuples work well for small hashable arrays.
- For large numeric arrays, a dtype-aware binary key is often more compact and efficient.
- Separate storage of raw payloads from indexing of lookup keys when persistence matters.
- Choose more specialized structures only when the query is something other than exact equality.
Related reading
- Efficient ways to sort a deck of actual cards
- Efficiently check if two numbers are co-primes relatively primes?
- Efficiently computing a - K / a K with improved accuracy
- Efficiently determine the parity of a permutation
- Efficient way to union two list with list or None value
- Efficiently convert edge list to adjacency list using MapReduce
- Efficiently find all connected induced subgraphs
- efficiently find amount of integers in a sorted array

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.