0

I have a tuple struct in my Python code that declares the following:

match_entry = (util.frozendict(rule_match), priority, version)

When I print match_entry, I see the following:

print match_entry
({'switch': 1, 'dstmac': 00:00:00:00:00:01, 'srcmac': 00:00:00:00:00:01}, 60000, 5)

I am searching for this particular tuple a dict of tuples, let's call it dict_of_tuples; the corresponding output for the dict is below.

print dict_of_tuples

{({'switch': 5, 'dstmac': '00:00:00:00:00:00', 'srcmac': '00:00:00:00:00:01'}, 59999, 7): [CountBucket 140271056467472, CountBucket 140271056411280], ({'switch': 5, 'dstmac': '00:00:00:00:00:00', 'srcmac': '00:00:00:00:00:01'}, 59999, 5): [CountBucket 140271056467472, CountBucket 140271056411280], ({'switch': 1, 'dstmac': '00:00:00:00:00:01', 'srcmac': '00:00:00:00:00:01'}, 60000, 5): [CountBucket 140271057099664, CountBucket 140271056501008]}

However, when I check if the match entry is in the tuple:

if match_entry in dict_of_tuples:

I do not see any results, even though the match_entry is clearly in dict_of_tuple. Any reason why this would be the case?

2 Answers2

0

Dictionary is not hashable, so I think your structure may not be possible:

>>> {({1:2, 2:3}, 2, 3): [1,2,3]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Dictionary doesn't allow a dict exists in its keys. So make sure it's really a dict not something like string.

Edit:

As mentioned in comment, a frozen dict (immutable dict) will be hashable therefore solves this problem. But you have to modify default dict type. Normally, you can modify a dict at runtime:

d = {}
d["key"] = "val"

It's enabled with __setattr__ in Object. When we need immutable classes? Basically, immutable objects are more efficient on memory. Here is a topic about this.

Community
  • 1
  • 1
knh170
  • 2,960
  • 1
  • 11
  • 17
  • The dict inside is a frozen dict. So it's hashable. – C Panda Apr 12 '16 at 16:54
  • 1
    @CPanda Ah, new knowledge. But I checked this: http://stackoverflow.com/questions/2703599/what-would-a-frozen-dict-be , and the test truly failed. I remembered frozen object can be created by manually modifying `__slot__`. – knh170 Apr 12 '16 at 16:56
  • Sorry mate, my bad. I have been thinking about frozen sets all along. – C Panda Apr 12 '16 at 16:59
  • Thanks, I didn't experience any TypeErrors because of the FrozenDicts. Turns out it was because the srcmac had been cast to a string in an earlier step. – user3772960 Apr 12 '16 at 19:16
0
        import frozendict as util
        from collections import defaultdict

        ### Create the first entry using hashable frozendict
        match = util.frozendict({'switch': 1, 'dstmac': '00:00:00:00:00:01', 'srcmac': '00:00:00:00:00:01'})
        match_array = tuple[match,60000,5]
        count_bucket2 = dict(CountBucket1 = 140271057099664, CountBucket2 = 140271056501008)

        ### Create the second entry using hashable frozendict
        match_entry = util.frozendict(switch= 5, dstmac= '00:00:00:00:00:00', srcmac= '00:00:00:00:00:01')
        match_array1 = tuple([match_entry, 59999, 7])

        count_bucket1 = dict(CountBucket1 = 140271056467472, CountBucket2 = 140271056411280)

        # Initialize the dictionary of tuples
        dict_of_tuples = ({tuple(match_array) : count_bucket2},{tuple(match_array1) : count_bucket1})

        ####### Your match entry
        match_entry = [{'switch': 1, 'dstmac': '00:00:00:00:00:01', 'srcmac': '00:00:00:00:00:01'},60000,5]                

    #Treating the final structure as a tuple. Each element of the tuple is a #dictionary.
        k = 0
        while k < len(dict_of_tuples):
            key = dict_of_tuples[k].iterkeys()
            val = dict_of_tuples[k].itervalues()
            if key.next() == tuple(match_entry):
                print ('Has key','corresponding value',val.next())
            else:
                print "Key not present"
            k+= 1
ForeverLearner
  • 1,901
  • 2
  • 28
  • 51