2
\$\begingroup\$

We can search for the list of dictionaries using the below some approaches, Can one please help me, which one is the memory efficient approach to use?

Provided that:

  • names are unique in the list
  • There will be definitely a name in each dictionary.

Where as:

items = [list_of_dicts]
name_to_b_searched = "some_name"

1 direct return from the for loop

def get_by_name(self, name_to_be_searched):
    for i in items:
        if i['name'] == name_to_be_searched:
              return i

2 Break from the for loop and return found dictionary

def get_by_name(self, name_to_be_searched):
    found = None
    for i in items:
        if i['name'] == name_to_be_searched:
              found = i
              break 
    return found

3 A generator function

def get_by_name(self, name_to_be_searched):
    for i in items:
        if i['name'] == name_to_be_searched:
              yield i

4 An inline generator

get_by_name =next(i for i in items if i['name'] == name_to_be_searched, None)

Sometimes I could have a huge csv records (in items), so was thinking which approach would be better to search a record. OR if there is any other approach you would recommend please let me know.

\$\endgroup\$
7
  • 4
    \$\begingroup\$ You did not define best. \$\endgroup\$ Nov 19, 2017 at 15:15
  • \$\begingroup\$ @StephenRauch - I did not get you \$\endgroup\$
    – Laxmikant
    Nov 19, 2017 at 17:01
  • 3
    \$\begingroup\$ You use the word best. This word has no specific technical meaning. \$\endgroup\$ Nov 19, 2017 at 17:03
  • \$\begingroup\$ Sadly, efficient is also technically ambiguous. \$\endgroup\$ Nov 19, 2017 at 17:09
  • 1
    \$\begingroup\$ Well, you could easily profile each piece of code you have and find out \$\endgroup\$ Nov 19, 2017 at 17:20

1 Answer 1

4
\$\begingroup\$

None of the above.

OR if there is any other approach you would recommend please let me know.

The whole point of using dictionaries is that you don't need to search anything and can access everything in O(1) (on average) instead of the O(n) in all of your suggestions.

  • names are unique in the list
  • There will be definitely a name in each dictionary.

So, instead of using a list of dictionaries, use a dictionary of dictionaries using the name as the outer key.

Instead of

items = [{'name': 'a', 'age': 22, ...},
         {'name': 'b', 'age': 30, ...}]

you should have

items = {'a': {'age': 22, ...},
         'b': {'age': 30, ...}}

Now you can access each dictionary directly by using the name.

name = 'b'
print(items[name]['age'])
#  30

No loops, no searches, O(1) access.

\$\endgroup\$
4
  • \$\begingroup\$ I agree. However could you show how you could get such a dictionary? \$\endgroup\$
    – Peilonrayz
    Nov 20, 2017 at 15:53
  • \$\begingroup\$ @Peilonrayz dict_of_dicts = {d['name']: d for d in list_of_dictionaries} Sacrificing a single O(n) iteration for many O(1) lookups in the future. \$\endgroup\$
    – DeepSpace
    Nov 20, 2017 at 15:56
  • 1
    \$\begingroup\$ thanks, however I was meaning more to add it to your answer, :) \$\endgroup\$
    – Peilonrayz
    Nov 20, 2017 at 15:58
  • \$\begingroup\$ OP is worried about memory and you recommend to use faster lookup by doubling the amount of used memory? \$\endgroup\$ Nov 21, 2017 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.