2017-09-12 80 views
6

Mam funkcję f, która pobiera int i zwraca bool. Chcę znaleźć minimalną nieujemną liczbę całkowitą x, dla której f(x) jest False. Jak mogę to zrobić w większości pythonic (najlepiej jednej linii)?Znajdź minimalną nieujemną liczbę całkowitą, która nie spełnia warunku.


Oto jak to zrobić teraz:

x = 0 
while f(x): 
    x += 1 
print(x) 

chcę coś takiego:

x = <perfect one line expression> 
print(x) 
+0

Nie jestem ekspertem jakie pythonic znaczenie, lecz trzy linie kodu są tym, co napisałbym i byłbym zadowolony. – VPfB

+0

@VPfB, w końcu używam mojego rozwiązania z trzema liniami zamiast rozwiązań jednoliniowych, ale ciekawe jest, jak można to zrobić w jednym wierszu :) – diraria

Odpowiedz

3

to jest tutaj, używając next:

from itertools import count 
x = next(i for i in count() if not f(i)) 

Demo:

>>> def f(x): 
...  return (x - 42)**2 
... 
>>> next(i for i in count() if not f(i)) 
42 
3

Podobne podejście funkcjonalne z itertools.filterfalse i itertools.count może być

from itertools import filterfalse, count 

x = next(filterfalse(f, count())) 

Można też zamienić się filterfalse z dropwhile, który podczas performantly podobny utrzymuje taką samą składnię całej Python 2 i 3 (dzięki rici).

from itertools import dropwhile, count 
x = next(dropwhile(f, count())) 
+0

Lub dropwhile, chociaż 2.7 kompatybilność nie wydaje się być konieczna. – rici

+0

@rici Po co martwić się 'dropwhile'? Myślę, że 'itertools.ifilterfalse' i dokładnie takie samo podejście działałoby dobrze. – miradulo

+1

Nie chciałem sugerować, że czas jest lepszy, ale nie wydaje mi się, że jestem gorszy. Jest to po prostu alternatywa, która ma tę samą pisownię w obu wersjach Pythona. – rici

1

Jeśli chcesz pojedynczą linię bez importu, jednym ze sposobów może być lista ze zrozumieniem (Python 2.7/pypy):

def f(x): 
    return True if x == 5 else False 

x = [g(0) for g in [lambda x: x if f(x) else g(x+1)]][0] 

print(x)