Mr_LinDowsMac
Mr_LinDowsMac

Reputation: 2702

Lookup for a key in dictionary with... regular expressions?

I have a dictionary that have the following structure: The key is a link between a source and a destination, the value is the instance of an object wire.

wire_dict = { source1_destination1_1 : object,
              source1_destination1_2 : object
              source2_destination1_3 : object
              source2_destination1_4 : object
              source2_destination2_1 : object
              source2_destination2_2 : object }

Let's suppose that I only have a destination value, and with that I want to find, perhaps with regular expressions, the key that have the destination1_1. As you can see, same sources can have several destinations, but different sources cannot have the same destinations. So I want to find the key that ends with the destination.

Since the wire_dict could contain a lot of key-value entries, please tell me how this approach can affect the performance of the application. Perhaps I should create another dictionary only for the relationship between source and destination?

UPDATE: I change the dictionary with tuples as keys:

wire_dict = { ('source1','destination1_1') : object1,
              ('source1','destination1_2') : object2
              ('source2','destination1_3') : object3
              ('source2','destination1_4') : object4
              ('source2','destination2_1') : object5
              ('source2','destination2_2') : object6 }

The logic of the application is the same. A destination cannot have more than one source. So, only a coincidence should be found when a destination is provided.

Upvotes: 3

Views: 6853

Answers (5)

yamm
yamm

Reputation: 1573

Object oriented programming my friend

class Uberdict():
    def init(source, destination, obj):
        self.source, self.destination, self.obj = source, destination, obj

    def has_destination(destination)
        # True or False
        return self.desination == destination

    def has_source(source)
        return self.source == source

wire_object_list = [
    # list of the objects
]
# how to create them
example_obj = Uberdict(some_source, some_destination, some_instance)
wire_object_list.append(example_obj)

# filter
example_destination = 'some destination'
filtered_list = [item for item in wire_object_list if item.has_destination(example_destination)

only psuedo code could have errors

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180401

You just need str.endswith and to iterate over the dict checking each key.

print([k for k in wire_dict if k.endswith("destination1_1")])

If there is only over one use next and a generator expression:

k = next((k for k in wire_dict if k.endswith("destination1_1")),"")

If you want the value use wire_dict.get(k) in case there is no match and you get an empty string returned from the next call.

In [18]: k = next((k for k in wire_dict if k.endswith("destination1_1")),"")

In [19]: wire_dict[k]
Out[19]: object

In [20]: k
Out[20]: 'source1_destination1_1'

You should also never use dict.keys in python2 unless you actually want a list. You can simply iterate over the dict object to access each key efficiently.

Upvotes: 0

warvariuc
warvariuc

Reputation: 59604

It's easy to run over all dict keys and find the ones that match your pattern, but it's slow for big dicts.

I think you need another dict with keys matching your destinations (as you thought).

Upvotes: 0

mike3996
mike3996

Reputation: 17497

Having string searches through dict keys is going to be linear time with standard python dictionaries. But it can be done with dict.keys() and re module as @avim helpfully told.

For the second concern, instead of string keys, how about having tuples as keys:

{(begin, end): connection_object}

It won't speed up at all (search is likely stay linear) but it enables better code behind the logic you want to express.

Upvotes: 3

sumit-sampang-rai
sumit-sampang-rai

Reputation: 691

import re
wire_dict = {'source1_destination1_1' : 'object1',
              'source1_destination1_2' : 'object2',
              'source2_destination1_3' : 'object3',
              'source2_destination1_4' : 'object4',
              'source2_destination2_1' : 'object5',
              'source2_destination2_2' : 'object6' }
pattern = 'source1_destination1_1'
print [value for key, value in wire_dict.items() if re.search(pattern, key)]

Output:

['object1']

Upvotes: 0

Related Questions