Python: get values ​​(objects) from a dictionary of objects in which one of the fields of an object matches a value (or condition)

I have a python dictionary whose keys are strings and the values ​​are objects.

For example, an object with one line and one int

class DictItem: def __init__(self, field1, field2): self.field1 = str(field1) self.field2 = int(field2) 

and dictionary:

 myDict = dict() myDict["sampleKey1"] = DictItem("test1", 1) myDict["sampleKey2"] = DictItem("test2", 2) myDict["sampleKey3"] = DictItem("test3", 3) 

What is the best / most efficient way to get dictionary entries that have a field of "field2"> = 2?

The idea is to create a “sub-dictionary” (the list will also do) only with elements in which field2> = 2 (in the example it will):

 { "sampleKey2": { "field1" : "test2", "field2": 2 }, "sampleKey3": { "field1" : "test3", "field2": 3 } } 

Is there a better way than to go through all the dictionary elements and check the condition? Maybe using itemgetters and lambda functions?

Thanks!

PS: I use Python2.4, just in case it is relevant

+6
python dictionary
source share
5 answers

To make a dict from a dict ,

 subdict = dict((k, v) for k, v in myDict.iteritems() if v.field2 >= 2) 
+8
source share
 mySubList = [dict((k,v) for k,v in myDict.iteritems() if v.field2 >= 2)] 

Documentation:

list-comprehensions , iteritems()

+4
source share

You must keep your various records - these are instances of "DicItem" - inside the list. A generator / list expression can easily filter out the desired results.

 data = [ DictItem("test1", 1), DictItem("test2", 2), DictItem("test3", 3), DictItem("test4", 4), ] 

and then:

 results = [item for item in data if item.field2 >= 2] 

This, of course, creates a linear filter. If you need more than linear speed for some of your queries, a container object for registers - in this case, the “list” should be a specialized class capable of creating data indexes there, as the DBMS does with its index table. This can be done easily by removing the class from the "list" and overriding the methods " append", "insert", "__getitem__", "__delitem__" and "pop" .

If you need this for a high profile application, I would suggest you take a look at some of the object-oriented database systems for Python, such as ZODB and others.

+3
source share

The idea is to create a “sub-dictionary” (the list will do too)

If you need a list, you can use filter (or itertools.ifilter ):

 result_list = filter(lambda x: x.field2 > 2, mydict.values()) 
+2
source share

"Most effective" will depend on how often the content of the dictionary changes compared to how often you perform the search.

If the dictionary changes frequently, and you perform the search less often, then the most effective method will be to go through iterations and select objects that match the criteria using the code published by Adam Bernier.

If the dictionary doesn't change much and you have a lot of searching, then it might be faster to make one or more reverse dictionaries, for example. one maps the values ​​of "field2" to a list of objects that have this value.

Alternatively, if you intend to execute complex queries, you can put all the data in the sqlite database in memory and let SQL sort it, possibly with ORM like SqlAlchemy

0
source share

All Articles