I have basic question about comprehension. There is list of dicts where values are lists, it looks like this:
listionary = [{'path': ['/tmp/folder/cat/number/letter', '/tmp/folder/hog/char/number/letter', '/tmp/folder/hog/number/letter', '/etc'],
'mask': True,
'name': 'dict-1'},
{'path': ['/tmp/folder/dog/number-2/letter-4', '/tmp/folder/hog-00/char/number-1/letter-5', '/tmp/folder/cow/number-2/letter-3'],
'mask': True,
'name': 'dict-2'},
{'path': ['/tmp/folder/dog_111/number/letter', '/tmp/folder/ant/char/number/letter', '/tmp/folder/hen/number/letter'],
'mask': True,
'name': 'dict-3'}]
What I need is to get from list-type values every unique animal. Animal is always between tmp/folder/ and next /. What I did:
import re
flat_list = [item for sublist in [i['path'] for i in listionary] for item in sublist]
animals = list(set([re.search('folder/([a-z]+)', elem).group(1) for elem in flat_list if 'tmp' in elem]))
It might be also compressed into one line, but it is quite complicated and unreadable:
animals = list(set([re.search('folder/([a-z]+)', elem).group(1) for elem in [item for sublist in [i['path'] for i in listionary] for item in sublist] if 'tmp' in elem]))
Is there any golden rule(e.g. zen of python) about size of comprehension? How can I make it better? Thank you in advance.
How can I make it better?
Here's how I would break down the last two points..
def get_animals(d):
animals = []
for item in d['path']:
if item.startswith('/tmp/folder/'):
animals.append(item[12:item.find('/',12)])
return animals
animals = set()
for d in dlist:
animals.update(get_animals(d))
animals = list(animals)