Czego nie powinniśmy robić w Pythonie? #1

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.

Porównywanie

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ć.

Iterowanie po słowniku

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))

Czekaj, stop!

Podoba Ci się to co tworzę? Jeśli tak to zapraszam Cię do zapisania się na newsletter:

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)
a w ramach prezentu otrzymasz całkowicie za darmo, dwa dokumenty PDF „6 (nie zawsze oczywistych) błędów popełnianych podczas nauki programowania” który jest jednym z efektów ponad siedmioletniej pracy i obserwacji rozwoju niejednego programisty oraz „Wstęp do testowania w Pythonie”, będący wprowadzeniem do biblioteki PyTest.
Jeśli to Cię interesuje to zapraszam również na swoje social media.

Jak i do ewentualnego postawienia mi kawy :)

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.

Pętla for

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

Zmierzając do brzegu

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 :)

Dzięki za wizytę,
Mateusz Mazurek
Mateusz M.

Pokaż komentarze

    • 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!

  • 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 🙂.

  • 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:)

Ostatnie wpisy

Podsumowanie: maj, czerwiec, lipiec i sierpień 2024

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

2 miesiące ago

Podsumowanie: kwiecień 2024

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

6 miesięcy ago

Podsumowanie: luty i marzec 2024

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

7 miesięcy ago

Podsumowanie: styczeń 2024

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

9 miesięcy ago

Podsumowanie roku 2023

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

10 miesięcy ago

Podsumowanie: grudzień 2023

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

11 miesięcy ago