Q: How to group identical collections together I am randomly sampling a number of matrices A and each one computing the probability mass function (pmf) for Ax.  x is random with elements from +-1 and A is a matrix with elements from +-1.  My code so far looks like:
from collections import Counter
import numpy as np
import itertools

def pmf(L):
    C = Counter(L)
    total = float(sum(C.values()))
    for key in C:
        C[key]/=total
    return C

N = 10

h = 2
n = 2**h
X = np.array(list(itertools.product([-1,1],repeat = n))).T

for _ in xrange(N):
    A = (np.random.randint(2, size=(h,n)))*2-1
    B = np.dot(A,X)
    probs = pmf([tuple(x) for x in B.T.tolist()])
    print probs

This gives, for example:
Counter({(0, 0): 0.375, (2, 2): 0.25, (-2, -2): 0.25, (-4, -4): 0.0625, (4, 4): 0.0625})
Counter({(0, 0): 0.25, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-2, -2): 0.125, (0, 4): 0.0625, (-4, 0): 0.0625, (4, 0): 0.0625, (0, -4): 0.0625})
Counter({(-2, 0): 0.1875, (0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625, (-4, -2): 0.0625})
Counter({(0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625})
Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
Counter({(0, 0): 0.25, (2, -2): 0.125, (2, 2): 0.125, (-2, -2): 0.125, (-2, 2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
Counter({(2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (2, 4): 0.0625, (4, 2): 0.0625})
Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})

I can collect together all the collections which are identical by hand and count how many I have of each. For example using the above output:
2     Counter({(-2, 0): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-4, 2): 0.0625, (4, -2): 0.0625, (-2, 4): 0.0625, (2, -4): 0.0625})
2     Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
1     Counter({(-2, 0): 0.1875, (0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625, (-4, -2): 0.0625})
1     Counter({(2, 0): 0.1875, (0, -2): 0.1875, (0, 2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (2, 4): 0.0625, (4, 2): 0.0625})
1     Counter({(0, 2): 0.1875, (2, 0): 0.1875, (0, -2): 0.1875, (-2, 0): 0.1875, (-4, -2): 0.0625, (-2, -4): 0.0625, (4, 2): 0.0625, (2, 4): 0.0625})
1     Counter({(0, 0): 0.375, (2, 2): 0.25, (-2, -2): 0.25, (-4, -4): 0.0625, (4, 4): 0.0625})
1     Counter({(0, 0): 0.25, (2, -2): 0.125, (2, 2): 0.125, (-2, -2): 0.125, (-2, 2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})
1     Counter({(0, 0): 0.25, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-2, -2): 0.125, (0, 4): 0.0625, (-4, 0): 0.0625, (4, 0): 0.0625, (0, -4): 0.0625})

However, what I would like is for each of these groups of identical collections to look at the matrices that caused them. So this would be two matrices for the first two groups above and 1 each for all the rest.  
What would be a good way to do this?

A: as you want to group each one by value, you can make a new dict with key the pmf-value and value a list/set of the matrix you have, and to help in this you can use a defaultdict with list/set. like this
from collections import Counter, defaultdict

test = Counter({(0, 0): 0.25, (-2, -2): 0.125, (-2, 2): 0.125, (2, 2): 0.125, (2, -2): 0.125, (-4, 0): 0.0625, (0, 4): 0.0625, (0, -4): 0.0625, (4, 0): 0.0625})

result = defaultdict(list)
for k,v in test.iteritems():
    result[v].append(k)
print result

#or more readable 
for k,v in result.iteritems():
    print k,v

output
0.25 [(0, 0)]
0.125 [(2, 2), (2, -2), (-2, -2), (-2, 2)]
0.0625 [(-4, 0), (0, 4), (0, -4), (4, 0)]

EDIT
Now, if you want to get the matrix A that produce a particular pmf-value, getting that from the pmf-value alone is imposible, so is needed to work around that by keeping track of each matrix that produce a particular pmf-value with the same defaultdict approach as before with the pmf as key and value a list of the matrix with that pmf, like this:
from collections import Counter, defaultdict
import numpy as np
import itertools

def pmf(L):
    C = Counter(L)
    total = float(sum(C.values()))
    for key in C:
        C[key]/=total
    return C

N = 10

h = 2
n = 2**h
X = np.array(list(itertools.product([-1,1],repeat = n))).T

result = defaultdict(list)

for _ in xrange(N):
    A = (np.random.randint(2, size=(h,n)))*2-1
    B = np.dot(A,X)
    probs = pmf([tuple(x) for x in B.T.tolist()])
    print probs
    result[ frozenset(probs.items()) ].append( A ) #append the one you need

now this part frozenset(probs.items()) is because a Counter is a unhashable object because is mutable and as such can't be used a dict key, so I need make it immutable by converting it to a frozenset of its items.
With this, now we have all the matrix that have a particular pmf
output
>>> for k,v in result.items():
        print k
        for A in v:
            print A
            print ""
        print "--------------------"


frozenset({((-4, 2), 0.0625), ((2, 0), 0.1875), ((4, -2), 0.0625), ((0, 2), 0.1875), ((-2, 4), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((2, -4), 0.0625)})
[[ 1  1 -1  1]
 [-1 -1  1  1]]

[[ 1  1 -1 -1]
 [-1  1  1  1]]

--------------------
frozenset({((2, 0), 0.1875), ((-2, -4), 0.0625), ((2, 4), 0.0625), ((0, 2), 0.1875), ((4, 2), 0.0625), ((0, -2), 0.1875), ((-2, 0), 0.1875), ((-4, -2), 0.0625)})
[[-1  1  1 -1]
 [ 1  1  1 -1]]

[[ 1  1  1 -1]
 [ 1 -1  1 -1]]

[[-1  1 -1  1]
 [-1  1  1  1]]

--------------------
frozenset({((0, 0), 0.25), ((-2, 2), 0.125), ((2, -2), 0.125), ((0, -4), 0.0625), ((0, 4), 0.0625), ((-4, 0), 0.0625), ((2, 2), 0.125), ((-2, -2), 0.125), ((4, 0), 0.0625)})
[[-1 -1 -1  1]
 [ 1  1 -1  1]]

[[-1  1  1 -1]
 [-1 -1 -1 -1]]

[[-1 -1 -1 -1]
 [ 1 -1  1 -1]]

[[ 1  1 -1  1]
 [ 1 -1  1  1]]

[[ 1  1  1  1]
 [-1 -1  1  1]]

--------------------
>>> 

