Python Basics — 9 protipów

1) enumerate — numeruj elementy w pętli

fruits = ["apple", "banana", "cherry"]
for i, f in enumerate(fruits, start=1):
    print(i, f)
1 apple
2 banana
3 cherry

Dlaczego warto: zamiast ręcznie liczyć indeksy.


2) zip — paruj listy w locie

names = ["Ala", "Bartek", "Cezary"]
scores = [84, 92, 78]
for name, score in zip(names, scores):
    print(f"{name}: {score}")
Ala: 84
Bartek: 92
Cezary: 78

Protip: list(zip(names, scores)) da listę krotek.


3) List Comprehension — szybko twórz listy

nums = [1, 2, 3, 4, 5]
squares_even = [x*x for x in nums if x % 2 == 0]
squares_even
[4, 16]

Mini-zadanie ✅

Wygeneruj listę długości każdego napisu w fruits, ale tylko dla owoców o nazwie dłuższej niż 5 znaków.

# TODO: uzupełnij list comprehension
fruits = ["apple", "banana", "cherry", "kiwi"]
# lengths = [...]
# lengths

4) Dictionary Comprehension — buduj słowniki efektywnie

products = ["laptop", "mouse", "keyboard", "monitor"]
prices = [2999, 59, 199, 899]
product_dict = {product: price for product, price in zip(products, prices) if price < 1000}
product_dict
{'mouse': 59, 'keyboard': 199, 'monitor': 899}

Protip: Możesz też tworzyć słowniki z warunkami: {k: v for k, v in items if condition}.


5) f-strings — formatuj stringi czytelnie

name = "Anna"
age = 25
score = 95.567
# Stary sposób
print("Nazywam się " + name + ", mam " + str(age) + " lat")
# f-string way 🚀
print(f"Nazywam się {name}, mam {age} lat i mój wynik to {score:.2f}")
Nazywam się Anna, mam 25 lat
Nazywam się Anna, mam 25 lat i mój wynik to 95.57

Dlaczego warto: Czytelniejsze i szybsze niż .format() czy konkatenacja.


6) collections.Counter — licz elementy automatycznie

from collections import Counter
grades = ["A", "B", "A", "C", "B", "A", "B", "C", "A"]
grade_counts = Counter(grades)
print(grade_counts)
print(f"Najczęstsza ocena: {grade_counts.most_common(1)[0][0]}")
Counter({'A': 4, 'B': 3, 'C': 2})
Najczęstsza ocena: A

Data Science tip: Idealne do analizy częstości kategorii w danych!


7) *args i **kwargs — elastyczne funkcje

def smart_print(*args, **kwargs):
    separator = kwargs.get('sep', ' | ')
    prefix = kwargs.get('prefix', '>>> ')
    print(prefix + separator.join(str(arg) for arg in args))

# Różne sposoby wywołania
smart_print("Python", "jest", "super")
smart_print("A", "B", "C", sep=" -> ", prefix="WYNIK: ")
smart_print(1, 2, 3, 4, 5, sep=", ")
>>> Python | jest | super
WYNIK: A -> B -> C
>>> 1, 2, 3, 4, 5

Dlaczego warto: Funkcje mogą przyjmować dowolną liczbę argumentów pozycyjnych (*args) i nazwanych (**kwargs).


8) defaultdict — słowniki z domyślnymi wartościami

from collections import defaultdict

# Standardowy słownik - trzeba sprawdzać klucze
normal_dict = {}
# if 'python' not in normal_dict:
#     normal_dict['python'] = []
# normal_dict['python'].append('awesome')

# defaultdict - automatyczne wartości domyślne
courses = defaultdict(list)
courses['python'].append('basics')
courses['python'].append('advanced')
courses['javascript'].append('react')

print(dict(courses))  # Konwersja do normalnego dict dla czytelności
{'python': ['basics', 'advanced'], 'javascript': ['react']}

Protip: defaultdict(int) dla liczników, defaultdict(list) dla grup, defaultdict(set) dla unikalnych wartości.


9) any() i all() — sprawdzaj warunki w kolekcjach

numbers = [2, 4, 6, 8, 10]
mixed_numbers = [1, 2, 3, 4, 5]
empty_list = []

# Czy wszystkie elementy są parzyste?
print(f"Wszystkie parzyste w {numbers}: {all(n % 2 == 0 for n in numbers)}")
print(f"Wszystkie parzyste w {mixed_numbers}: {all(n % 2 == 0 for n in mixed_numbers)}")

# Czy którykolwiek element jest większy niż 5?
print(f"Jakiś > 5 w {numbers}: {any(n > 5 for n in numbers)}")
print(f"Jakiś > 5 w {mixed_numbers}: {any(n > 5 for n in mixed_numbers)}")

# Edge case - pusta lista
print(f"all([]) = {all(empty_list)}")  # True (bo nie ma elementów fałszywych)
print(f"any([]) = {any(empty_list)}")  # False (bo nie ma elementów prawdziwych)
Wszystkie parzyste w [2, 4, 6, 8, 10]: True
Wszystkie parzyste w [1, 2, 3, 4, 5]: False
Jakiś > 5 w [2, 4, 6, 8, 10]: True
Jakiś > 5 w [1, 2, 3, 4, 5]: False
all([]) = True
any([]) = False

Data Science tip: Świetne do walidacji danych - all(df['age'] > 0) sprawdzi czy każdy wiek jest dodatni!


Finalne wyzwanie 🏆

Stwórz funkcję analyze_grades(grades_list), która:

  1. Przyjmuje listę ocen (stringi: “A”, “B”, “C”, “D”, “F”)
  2. Zwraca słownik z informacjami:
    • counts: liczba każdej oceny (użyj Counter)
    • has_failing: czy są oceny F (użyj any())
    • all_passing: czy wszystkie oceny to A-D (użyj all())
    • top_grade: najczęstsza ocena
from collections import Counter

def analyze_grades(grades_list):
    # TODO: Uzupełnij funkcję
    # counts = ...
    # has_failing = ...
    # all_passing = ...
    # top_grade = ...
    # return {...}
    pass

# Test
test_grades = ["A", "B", "A", "C", "B", "A", "D", "C", "A"]
# result = analyze_grades(test_grades)
# print(result)