Mam kod, który wygląda mniej więcej tak:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
ok, więc to jest uproszczone, ale masz pomysł. Teraz thing
może nie być na liście, w takim przypadku chcę przekazać -1 jako thing_index
. W innych językach tego można się spodziewać, index()
gdyby nie mógł znaleźć elementu. W rzeczywistości rzuca ValueError
.
Mógłbym to zrobić:
try:
thing_index = thing_list.index(thing)
except ValueError:
thing_index = -1
otherfunction(thing_list, thing_index)
Ale to wydaje się brudne, a ponadto nie wiem, czy ValueError
można by go podnieść z innego powodu. Wymyśliłem następujące rozwiązanie oparte na funkcjach generatora, ale wydaje się ono nieco skomplikowane:
thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]
Czy istnieje czystszy sposób na osiągnięcie tego samego? Załóżmy, że lista nie jest posortowana.
thing_index
”. - To jest zdecydowanie nie-Pythonic. Przekazywanie (bezsensownej) wartości tokenu w przypadku, gdy operacja się nie powiedzie, jest mile widziane - wyjątki są tutaj naprawdę właściwą drogą. Zwłaszcza, żething_list[-1]
jest to prawidłowe wyrażenie, czyli ostatni wpis na liście.str.find
metoda, która dokładnie to robi: zwraca,-1
gdy igła nie została znaleziona w temacie.str.index()
zgłasza wyjątek, jeśli szukany ciąg nie zostanie znaleziony.Odpowiedzi:
Nie ma nic "brudnego" w używaniu klauzuli try-except. To jest sposób pytoniczny.
ValueError
zostanie podniesiony tylko przez.index
metodę, ponieważ jest to jedyny kod, który tam masz!Odpowiadając na komentarz:
W Pythonie łatwiej prosić o przebaczenie niż o pozwolenie filozofia jest dobrze ugruntowana i nie
index
spowoduje to powstania tego typu błędu w innych kwestiach. Nie to, żebym wymyślił jakiekolwiek.źródło
{}.get(index, '')
bardziej pytoniczne? Nie wspominając o krótszym, bardziej czytelnym.None
zamiast -1 byłoby w porządku, ale jak sam skomentowałeś, str.find () zwraca -1, więc dlaczego nie miałaby istnieć list.find (), która robi to samo? Nie kupuję argumentu „otherfunction
. Z drugiej strony, jeśli się nie zepsuł, ...Jedna linia. Prosty. Bez wyjątków.
źródło
for
.indexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
Plik
dict
Typ posiadaget
funkcję , gdzie jeśli klucz nie istnieje w słowniku, 2nd argumentget
jest wartością, którą należy zwrócić. Podobnie jestsetdefault
, który zwraca wartość w,dict
jeśli klucz istnieje, w przeciwnym razie ustawia wartość zgodnie z domyślnym parametrem, a następnie zwraca parametr domyślny.Możesz rozszerzyć
list
typ, aby miećgetindexdefault
metodę.Które można następnie wykorzystać na przykład:
źródło
Nie ma nic złego w Twoim kodzie, który używa
ValueError
. Oto kolejna jedna linijka, jeśli chcesz uniknąć wyjątków:źródło
next()
funkcja istnieje w Pythonie 2.6+. Ale jest łatwy do zaimplementowania dla 2.5, zobacz implementację funkcji next () dla Pythona 2.5Ta kwestia dotyczy filozofii języka. Na przykład w Javie zawsze istniała tradycja, że wyjątki powinny być używane tylko w „wyjątkowych okolicznościach”, czyli wtedy, gdy wystąpiły błędy, a nie do sterowania przepływem . Na początku było to spowodowane wydajnością, ponieważ wyjątki Java były powolne, ale teraz stało się to akceptowanym stylem.
W przeciwieństwie do tego Python zawsze stosował wyjątki, aby wskazać normalny przepływ programu, na przykład podnosząc a,
ValueError
o czym tutaj mówimy. Nie ma w tym nic "brudnego" w stylu Pythona, a jest ich o wiele więcej. Jeszcze bardziej powszechnym przykładem jestStopIteration
wyjątek, który jest zgłaszany przez metodę iteratora,next()
aby zasygnalizować, że nie ma dalszych wartości.źródło
StopIteration
ponieważ jest jasno określone, co oznacza wyjątek.ValueError
jest trochę zbyt ogólne.Jeśli robisz to często, lepiej wypalić go w funkcji pomocniczej:
źródło
A co z tym 😃:
źródło
A co z tym:
Zamiast ujawniać coś tak zależnego od implementacji, jak indeks listy w interfejsie funkcji, przekaż kolekcję i coś i pozwól innej funkcji zająć się kwestiami „testu członkostwa”. Jeśli inna funkcja jest napisana jako niezależna od typu kolekcji, prawdopodobnie zaczęłaby się od:
co zadziała, jeśli thing_collection jest listą, krotką, zestawem lub dyktowaniem.
Jest to prawdopodobnie jaśniejsze niż:
czyli kod, który już masz w innej funkcji.
źródło
A co z tym:
źródło
Mam ten sam problem z metodą „.index ()” na listach. Nie mam problemu z tym, że zgłasza wyjątek, ale zdecydowanie nie zgadzam się z faktem, że jest to nieopisowy ValueError. Zrozumiałbym, gdyby był to błąd IndexError.
Rozumiem, dlaczego zwrócenie „-1” również byłoby problemem, ponieważ jest to prawidłowy indeks w Pythonie. Ale realistycznie, nigdy nie oczekuję, że metoda „.index ()” zwróci liczbę ujemną.
Tutaj przechodzi jeden wiersz (ok, to dość długa linia ...), dokładnie raz przechodzi przez listę i zwraca „Brak”, jeśli element nie zostanie znaleziony. Przepisanie go na wartość -1 byłoby trywialne, gdybyś sobie tego życzył.
Jak używać:
źródło
Nie wiem, dlaczego uważasz, że jest brudny ... z powodu wyjątku? jeśli chcesz oneliner, oto jest:
ale odradzałbym go używać; Myślę, że rozwiązanie Rossa Rogersa jest najlepsze, użyj obiektu do hermetyzacji swojego zamierzonego zachowania, nie próbuj przesuwać języka do jego granic kosztem czytelności.
źródło
find()
funkcji i będzie on czysty;)Proponuję:
źródło