Search code examples
pythonlist-comprehension

Pythonic way to a double comprehension


I have to get a list of handles and labels from a figure, except in the cases where the label is "True" or "False". The following code accomplishes this:

# h, l = [a for a in ax.get_legend_handles_labels()] #redundant
h, l = ax.get_legend_handles_labels()
handles = [a for a, b in zip(h, l) if (b != 'True' and b != 'False')]
labels = [b for a, b in zip(h, l) if (b != 'True' and b != 'False')]

Nevertheless, this seems completely "not-pythonic". Is there a more elegant way to solve this? I tried the following 2-liner but I got a ValueError: too many values to unpack (expected 2) on line 2:

h, l = [a for a in ax.get_legend_handles_labels()]
handles, labels = [(a,b) for a, b in zip(h, l) if (b != 'True' and b != 'False')]

I'd expect Python to have a one-line solution...is there any?

For reproducibility:

(h,l)=(['handle1','handle2', 'handle3'],['label1','True', 'False'])
handles = [a for a, b in zip(h, l) if (b != 'True' and b != 'False')]
labels = [b for a, b in zip(h, l) if (b != 'True' and b != 'False')]

The intended output for this reproducible example is

handles=['handle1'] 
labels=['label1']

Solution

  • You can use zip again:

    h, l = [a for a in ax.get_legend_handles_labels()]
    filtered_hl = [(a,b) for a, b in zip(h, l) if (b != 'True' and b != 'False')]
    handles, labels = map(list, zip(*filtered_hl))