Programowanie w każdym języku wygląda podobnie. To, co je różni, to detale. Pisząc to słowo mam na myśli pewne rozwiązania, które są dedykowane dla tego jednego, konkretnego języka. Python nie jest tutaj wyjątkiem, natomiast jego elastyczność pozwala tworzyć kod, który jest daleki od ideału. Przy akompaniamencie tego zdania pokażę dziś kilka rozwiązań, które nigdy nie powinny się pojawić w plikach z rozszerzeniem .py.
Bardzo często widzę instrukcje warunkowe pisane w taki sposób:
1 2 3 4 | some_variable = None if some_variable == None: do_something() |
Najczęściej piszą je ludzie, którzy już pisali w innym języku i nie bardzo wiedzą, że powinni inaczej. Poprawnie (tj. zgodnie z PEP8) jest używać operatora is:
1 2 3 4 | some_variable = None if some_variable is None: do_something() |
Podobnie ma się sprawa z porównywaniem zmiennych True/False, tj zamiast porównywania w formie
1 2 3 4 | some_variable = False if some_variable == True: do_something() |
lub
1 2 3 4 | some_variable = False if some_variable is True: do_something() |
powinniśmy po prostu zrobić:
1 2 3 4 | some_variable = False if some_variable: do_something() |
To co tu jest ważne i pojawiło się kilka razy w komentarzach gdzieś na social media to to czym różni się is od ==. Operator „==” sprawdza równość obiektów a operator „is” sprawdza czy to te same obiekty. Ładnie to widać tutaj:
1 2 3 4 5 6 7 8 9 | list1 = [] list2 = [] list3 = list1 print(list1 == list2) print(list1 is list2) print(list1 is list3) |
gdzie output to:
True
False
True
więc to co chciałbym dodać to to że ten punkt dotyczy porównywania z None’em i z True/False – w innych przypadkach efekty stosowania is mogą być różne i warto to wiedzieć.
Gdybym miał dostać złotówkę za każdym razem, kiedy widzę coś takiego jak poniżej, to byłbym bardzo bogatym człowiekiem:
1 2 3 4 | d = {"some_key": "some_val", "some_key2":"some_val3"} for key in d: print("{} have value {}".format(key, d[key])) |
I nie mam na myśli tu tylko juniorów! Jedynym słusznym zapisem jest:
1 2 3 4 | d = {"some_key": "some_val", "some_key2":"some_val3"} for key, val in d.items(): print("{} have value {}".format(key, val)) |
Uwaga! Poniższe wtrącenie związane z items() / iteritems() jest zasadne tylko dla Pythona 2! W Pythonie 3 funkcja iteritems() nie istnieje, a items() działa używając generatora.
To, o czym powinno się pamiętać to, że funkcja items() nie jest demonem szybkości. Znacznie lepszym rozwiązaniem jest funkcja iteritems() czyli:
1 2 3 4 | d = {"some_key": "some_val", "some_key2":"some_val3"} for key, val in d.iteritems(): print("{} = {}".format(key, val)) |
Mimo że różnicy w sposobie użycia nie ma, to pod spodem funkcja items() tworzy nam tuple, co jest dość kosztownym podejściem, natomiast funkcja iteritems() zwraca generator.
Idąc dalej – w pętli for czasem potrzebujemy dostać się do aktualnego indeksu. Potrzeba w wielu przypadkach zasadna, ale wykonanie na pewno nie powinno wyglądać tak:
1 2 3 4 5 | elements = ['first', 'second', 'third'] for i in range(len(elements)): element = elements[i] print(i, element) |
jeśli chcemy zrobić to po pythonowemu, użyjmy enumerate():
1 2 3 4 | elements = ['first', 'second', 'third'] for i, element in enumerate(elements): print(i, element) |
To, co warto wiedzieć albo może bardziej, to czego warto być świadomym to działanie funkcji enumerate(). Może po prostu zerknijcie na kod, który mógłby być jej definicją:
1 2 3 4 5 | def enumerate(sequence, start=0): n = start for elem in sequence: yield n, elem n += 1 |
Niech ten, kto nigdy nie napisał takiego kodu, pierwszy rzuci kamień…
Tytuł posta ma w sobie „#1” – i poprawnie sugeruje, że artykułów z tej serii będzie więcej. Mam nadzieję, że dzięki temu wpisowi Wasze kody będą coraz lepsze :)
Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More
Cześć! Zapraszam na krótkie podsumowanie kwietnia. Wyjazd do Niemiec A dokładniej pod granicę z Francją. Chrześnica miała pierwszą komunię. Po… Read More
Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More
Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More
Pokaż komentarze
Wszystko fajnie ale może wyjaśnisz czemu is a nie =?
Operator "==" sprawdza równość obiektów a operator "is" sprawdza czy to te same obiekty. Ładnie to widać tutaj:
list1 = []
list2 = []
list3 = list1
if (list1 == list2):
print("True")
else:
print("False")
if (list1 is list2):
print("True")
else:
print("False")
if (list1 is list3):
print("True")
else:
print("False")
I to zwróci:
True
False
True
Dodatkowo w
if some_variable:
do_something()
będzie spełniony warunek nawet kiedy some_variable != True, np w przypadku gdy sime_variable będzie niepustym stringiem
Potwierdzam, wartość stringa jak jest rzutowany na bool'a jest zależna od jego długości i jak ma długość zero to jest False:)
Krótka, rzeczowa i przydatna treść! Ostatnio zaczynam więcej pisać w Pythonie, ze względu na studia i zagłębianie tematyki uczenia maszynowego, dlatego takie artykuły wpasowują się idealnie. Pozdrawiam!
Dzięki ogromne za miły komentarz!
Przydatny artykuł. Mysle ze przedstawione przyklady poprawnego programowania w Pythonie przekladaja sie glownie na zlozonosc czasowa wykonania sie programu.
Sam zaczynam programowac w Python i na pewno bede sledzil kontynuacje.
Pozdrawiam 🙂.
Cieszę się że doceniasz, dzięki!
Aktukuł całkiem fajnie napisany, krótko, zwięźle i na temat. Jednak przyczepie się do dwóch rzeczy. 1. piszesz, że iteritems() jest tylko w Python 2, używasz Pythona 3 i wywołujesz metodę słownika iteritems zamiast items. 2. funkcja range iteruje od 0, wiec nie trzeba podawać pierwszego parametru czyli wystarczy napisać range(len(elements)).
Cześć! Dzięki za pozytywny komentarz:) co do 1 pkt to kod pod "Uwaga! Poniższe wtrącenie związane z items() / iteritems() jest zasadne tylko dla Pythona 2! W Pythonie 3 funkcja iteritems() nie istnieje, a items() działa używając generatora." jest w Pythonie 2, w Pythonie 3 nie uruchomiłby się (brak iteritems().
Punkt 2 - poprawiłem:)
Wiele bym dal, aby nie tylko przeczytac czego nie robic, ale takze DLACZEGO...
pisze to z perspektywy osoby, ktora pythona od 2 miesiecy sie uczy ;)
Cześć, dzięki za komentarz. Tam gdzie jest to koniecznie wskazuje powód np. opisuję prędkość lub wskazuje plusy rozwiązania a jeśli brak to jest to po prostu wygodniejsze i/lub bardziej Python'owe rozwiązanie:)