'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 1:[1]
There is a technique called "unzipping" an iterator (see fourth line in my code example), which is kind of a reshape of nested elements. It's a little bit like numpy's swapaxes if you are familiar with it. Combining python's iterators zip and filter you can achieve the desired behaviour in the following way:
h, l = ax.get_legend_handles_labels()
zipped = zip(h, l)
filtered = filter(lambda t: t[1] != 'True' and t[1] != 'False', zipped)
handles, labels = zip(*filtered)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alex G |
