A one-liner for result
, and a one-liner for res
:
result = max([[*map(int,d.split(','))] for d in lines], key=lambda p: math.log(*p))
res = math.log(*result)
tada
What magic is this?
One point to realise is that result
will end up being only one list of length two: [body, exp]
. And this list is decided by logr > res
—a key to sort by—implying the use of min
, sorted
, max
, or similar.
The issue with immediately evaluating the log, as demonstrated in the attempt in the question, is that we lose the values obtained from split(', ')
. But we need these values for result
! Instead, keep the values, determine the correct pair first, and evaluate the log afterwards.
Now down to the one-liners. The first part of the comprehension is fairly straightforward.
[[*map(int,d.split(','))] for d in lines]
This creates a list of lists of parsed lines.
["111,222", "333,444", "555,666"] # before (lines)
[[111, 222],
[333, 444],
[555, 666]] # after (list comp.)
We then select the pair which has the highest log. In other words, we take the max
, comparing by a key of key=lambda p: math.log(*p)
(i.e. compare by the log).
(In case you were wondering what the asterisk does, it unpacks the given iterable (see What does the star operator mean? for more info). In this particular case, math.log(*p)
is the same as math.log(p[0], p[1])
.)
Once we've selected our result, we throw it into math.log
again to compute res
.
And all ends well.