Oct-24-2020, 07:33 PM
(This post was last modified: Oct-25-2020, 11:39 AM by osxtra.
Edit Reason: Adjusted bbcode for readability; if statement in function to comply with PEP8 guidelines.
)
Hi, all,
Python 3.9, compiled from source on OSX 10.13.6
After a fair amount of experimentation and searching the inter-tubes, I have a few questions about searching lists of lists based on partial matches to the list items.
Sorry for the earlier indentation issue. Was apparently not using the bbcode properly...
Assuming:
Searching for 'val4' would return the 3rd dictionary entry, i.e.,
>>> print(f"{my_search('val4', my_list)}")
>>> {'name': ['val4a', 'val5'], 'id': '44256'}
I do want the entire dictionary returned as there may be other key/value pairs in each dictionary entry, and additional processing based on their contents.
The questions:
(Getting the comprehension to iterate each dictionary's list items in one pass has been troublesome. If I specify the index of the list item in the comprehension, it works, but then I'm stuck just searching that one entry in the list, not all the items it contains.)
Any pointers would be most welcome. Thanks!
Python 3.9, compiled from source on OSX 10.13.6
After a fair amount of experimentation and searching the inter-tubes, I have a few questions about searching lists of lists based on partial matches to the list items.
Sorry for the earlier indentation issue. Was apparently not using the bbcode properly...
Assuming:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
my_list = [{ 'name' : [ 'myvar' , 'val1' , 'val2' ], 'id' : '181' }, { 'name' : [ 'val3' ], 'id' : '9205' }, { 'name' : [ 'val4a' , 'val5' ], 'id' : '44256' }] search = 'val5' def my_search(search, entries): """ Return a dictionary entry upon matching criteria, or None """ result = None search = search.lower() for i in entries: if [k for k in [i.lower() for i in i[ 'name' ]] if search in k]: result = i break return result |
>>> print(f"{my_search('val4', my_list)}")
>>> {'name': ['val4a', 'val5'], 'id': '44256'}
I do want the entire dictionary returned as there may be other key/value pairs in each dictionary entry, and additional processing based on their contents.
The questions:
- Is there a way to reduce code in the function by employing another list comprehension, for 'i', or is this the best method for searching the dictionary entries? I'd like to get it down to one line if possible, without the outer 'for i in entries:' loop. (For extra credit, would love to be able to just return the result of a single comprehension, or None, as needed.)
- The dictionary may grow, but is currently fairly small, say a couple of dozen dozen entries with each target search list containing one to six or so items. Is it recommended, performance-wise, to force the search to be lower case before iterating the dictionary entries, or is it just as good having it be in the comprehension with search.lower() instead? The former would seem to be preferable as it only has to do the conversion once, rather than for each list being searched. The search itself does need to be lower-case so as to standardize what's being evaluated, or it might not match ('Val3' vs 'val3', etc.).
- Is there a better way to search the list items in a case-insensitive manner without first creating 'j' (the lower-case list for each dictionary entry)? Doing it this way means I'm effectively iterating each dictionary entry's list twice, but either it has to be lower case as mentioned above, or all the list items need to be lower and that could complicate displaying a 'prettyfied' search result.
- Is there a better method for returning the target dictionary entry, or do I need to store it in 'result' as I'm doing now and return it when the search is successful?
(Getting the comprehension to iterate each dictionary's list items in one pass has been troublesome. If I specify the index of the list item in the comprehension, it works, but then I'm stuck just searching that one entry in the list, not all the items it contains.)
Any pointers would be most welcome. Thanks!