Your specification is incomplete. For cases without non-None elements, itâs impossible. (You cover that in the âextra creditâ version, but not in the main version.)
True 49 [i for i, e in enumerate(L) if e is not None][-1]
True 40 max(i for i,x in enumerate(L)if x!=None)
True 39 len(L)+~[*map(type,L)][::-1].index(int)
True 32 ~[*map(type,L)][::-1].index(int)
Tester:
L = [None, 3, None, 1, None, 4, 0, None, None, None, None]
codes = '''\
[i for i, e in enumerate(L) if e is not None][-1]
max(i for i,x in enumerate(L)if x!=None)
len(L)+~[*map(type,L)][::-1].index(int)
~[*map(type,L)][::-1].index(int)
'''.splitlines()
for c in codes:
idx = eval(c)
correct = isinstance(L[idx], int) and all(i is None for i in L[idx + 1 :])
print(correct, len(c.strip()), c)
Argh, it actually sometimes âfailsâ the test as written, for example for L = [3], since I compute -1 and then all(i is None for i in L[idx + 1 :]) is false. But I claim the test is wrong and the index is correct
Tests all (solvable) cases with up to 10 elements of None, 0 and 1.
Using all(i is None for i in L[idx + 1 or len(L):]) (added or len(L)), to accept idx = -1 when thatâs where the last non-None is.
from itertools import product
codes = '''\
[i for i, e in enumerate(L) if e is not None][-1]
max(i for i,x in enumerate(L)if x!=None)
len(L)+~[*map(type,L)][::-1].index(int)
~[*map(type,L)][::-1].index(int)
'''.splitlines()
Ls = []
for n in range(11):
it = product((None, 0, 1), repeat=n)
next(it)
Ls += it
for c in codes:
cc = compile(c, '', 'eval')
correct = all(
isinstance(L[idx], int) and all(i is None for i in L[idx + 1 or len(L):])
for L in Ls
for idx in [eval(cc)]
)
print(correct, len(c.strip()), c)
Traversing from the back should always win (regarding number of operations). This needs to be done in a function call so we can return immediately rather than finish entire traversal
def find_not_none(L: list[int | None]):
for i, val in enumerate(reversed(L)):
if val is not None:
return len(L) - 1 - i
return 0 # For your extra credit
idx = find_not_none(L)
Code golfing isnât about number of operations, though. Frequently the winners are rather the opposite, brute force solutions using huge numbers of operations even when few would suffice.
Yes, Iâm only doing the main version, not the "extra creditâ version.
The list must contain a non-None value, otherwise the task wouldâve specified what to do if thatâs not the case. And Alexanderâs original code, declared to be a solution, likewise âfailsâ on such unsolvable input. Put differently, as itâs not specified what to do in such cases, anything is allowed with them, so itâs not failing.