Looking for an efficient method to search for partial strings in Python (3.6+) lists.
I have two lists. listA is a list of strings of pathname + a unique filename:
['/pathname/uniquestring.ext', '/pathname/uniquestring.ext', '/pathname/uniquestring.ext' ...]
(created using glob(), filenames are all given and already exist)
listB is a list of dictionaries. Each dictionary has the same set of keys, but unique values.
[{key1:value1, key2:value2}, {key1:value3, key2:value4}, ...]
(also already given)
One key:value pair in each dictionary in listB will have a value that is contained in one unique item in listA.
However, the position of the value as it appears in each item of listA is indeterminate.
What I wanted was: for each item in listB, find the item in listA that contains a substring matching the k:v pair in the dict, and create a new dict (or list of tuples) as a "lookup table" (the goal was to correct a corrupted exif creation date in a set of image files).
Example:
listA = ['/pathname/abdce_654321.ext', '/pathname/a3b4c5_123456.ext', '/pathname/cbeebie_645321_abcde.ext', ...]
listB = [{"id": "123456", "create_date": "23/05/2014"}, ...]
new_dict = {"/pathname/a3b4c5_123456.ext": "23/05/2014, ...}
I've got exactly what I want from a dict comp as follows:
{j:i['create_date'] for j in listA for i in listB if i['id'] in j}
But, even for my very small files (~5500 items) this takes 12s on my (admittedly rather old) laptop.
Presumably this is because I have to iterate over the whole of listB ~5500 times using my method.
Is there a more efficient way to do this in Python?
(nb i'm not seeking advice on how to correct exif data with python; this is a generalised q about string lookups in lists)
CORRECTIONS & CLARIFICATIONS
- I neglected to place quotes around the value '123456' in my example, implying of course that it is an integer; In the real-world data, it isn't, and nor are any of the equivalent values in the actual data I dealt with.
- The 'id' substring as it appears in a listA item is almost always delimited by underscores, but does not always appear in the same position in the whole string; So, performing a split('_') for instance on each item won't always place the 'id' string at position [-1] or [-2] or [-3], although [-1] would take care of ~80% of cases.
- All 'id's are unique, they do not appear more than once in either list; each filename is unique in listA; each 'id' never appears in more than one dictionary.
Thanks for the interest from everyone so far btw.