Reputation: 2702
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
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
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
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
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
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