How to handle a dict variable with 2^50 elements?
I'd go for something like this:
Open 16 files (opened in binary mode should be fine; this will be easiest if all your strings have the same length). Generate your strings and hashes, and write them to a file depending on the first 4 bit of the hash. Then load and process each file separately. This will reduce memory usage by a factor of 16. (Of course you can use any number of files as long as you don't run out of file handles. Having to open and close each file on every access will become rather slow.)
If generating the strings and hashes is relatively inexpensive, you don't even need the files. Simply do 16 passes, and in each pass keep only thoses hashes the upper nibbles of which match the pass number.
One way to solve the problem is to use a very long bitfield, so that every hash is mapped to certain position in 2^25
bits long memory block.
A better, yet non-100%-assurance manner to solve this kind of problems is done via Bloom filter or other probabilistic data structures.
A Bloom filter is a space-efficient probabilistic data structure that is used to test whether an element is a member of a set. False positives are possible, but false negatives are not; i.e. a query returns either "inside set (may be wrong)" or "definitely not in set".
Bloom filters have a strong space advantage over other data structures for representing sets, such as self-balancing binary search trees, tries, hash tables, or simple arrays or linked lists of the entries.
A Bloom filter with 1% error requires only about 9.6 bits per element — regardless of the size of the elements.
So, 9.6 bits per 2^25 elements, will need just 38.4 MiB of memory.