Jak obsłużyć plik CSV w Pythonie bez zewnętrznych bibliotek

Marek Radoszewski Marek Radoszewski
Narzędzia i Praktyki
03.02.2026 11 min
Jak obsłużyć plik CSV w Pythonie bez zewnętrznych bibliotek

Jak obsłużyć plik CSV w Pythonie bez bibliotek zewnętrznych?

Zdarza Ci się pracować z danymi i trafiasz na pliki CSV? To jeden z najpopularniejszych i najprostszych formatów do wymiany informacji. W świecie Pythona naturalnym wyborem do jego obsługi jest wbudowany moduł csv. Ale co, jeśli powiem Ci, że jak obsłużyć plik CSV w Pythonie bez bibliotek zewnętrznych wcale nie jest wiedzą tajemną, a wręcz kluczową do głębszego zrozumienia tego, jak działają dane?

Właśnie to pytanie rozłożymy dziś na czynniki pierwsze. Przygotuj się na solidną dawkę praktycznej wiedzy, która pozwoli Ci samodzielnie, linia po linii, przetwarzać pliki CSV. Zapomnij na chwilę o importowaniu zewnętrznych modułów – skupimy się na surowej sile Pythona i Twojej zdolności do rozwiązywania problemów. Gotowy? Zaczynamy!

Możesz zastanawiać się, po co w ogóle zajmować się ręcznym przetwarzaniem pliku CSV, skoro Python ma fantastyczną bibliotekę csv, która robi większość roboty za Ciebie. Odpowiedź jest jednak prostsza, niż myślisz, i ma kilka ważnych aspektów związanych z nauką, optymalizacją i niezależnością od zewnętrznych zależności.

Poznasz tu zarówno podstawy formatu CSV, jak i konkretne przykłady kodu w Pythonie, które pokażą Ci, jak taki plik otworzyć, wczytać, przetworzyć oraz zapisać z powrotem. Dzięki temu zrozumiesz, jak dane tekstowe są obsługiwane na najniższym poziomie i jak możesz je świadomie kontrolować.

Programista analizuje plik CSV w Pythonie bez bibliotek zewnętrznych, linia po linii, na ekranie z kodem i danymi tabelarycznymi

Dlaczego warto umieć ręcznie obsłużyć plik CSV w Pythonie?

Możesz zastanawiać się, po co uczyć się czegoś „na piechotę”, skoro dostępny jest wygodny moduł csv. Ta umiejętność ma jednak kilka kluczowych zalet, które wpływają na Twój rozwój jako programisty i na sposób, w jaki podchodzisz do danych.

Głębsze zrozumienie danych i formatu CSV

Po pierwsze, fundamentalne zrozumienie tego, jak dane są reprezentowane i przetwarzane na najniższym poziomie, jest bezcenne. Kiedy samodzielnie rozkładasz plik CSV na czynniki pierwsze, zyskujesz lepsze wyczucie jego struktury i potencjalnych pułapek.

To trochę jak nauka jazdy na rowerze bez kółek – początkowo może być trudniej, ale później czujesz „rower” znacznie lepiej. Z czasem zaczynasz zauważać różne niuanse, takie jak separatory, białe znaki czy problemy z kodowaniem, które inaczej mogłyby umknąć Twojej uwadze.

Niezależność od zewnętrznych bibliotek i środowiska

Drugim ważnym powodem jest uniezależnienie od zależności. Czasami pracujesz w środowiskach, gdzie instalowanie dodatkowych pakietów jest niemożliwe lub mocno utrudnione. Może to być serwer o zaostrzonych zasadach bezpieczeństwa albo prosty system, w którym liczy się minimalizm.

Być może budujesz mały skrypt, który musi działać wszędzie, bez żadnych pip install. W takich sytuacjach podstawowe operacje na plikach, oparte wyłącznie na standardowych możliwościach Pythona, to Twoi najlepsi przyjaciele.

Optymalizacja pod konkretny przypadek użycia

Kolejnym aspektem jest optymalizacja pod konkretne wymagania. Moduł csv jest bardzo wszechstronny, ale ta wszechstronność czasem wprowadza pewien narzut. Jeśli masz bardzo prosty, przewidywalny format danych, ręczna implementacja może być:

  • czytelniejsza w kodzie,
  • szybsza w działaniu,
  • lepiej dopasowana do Twojego przypadku.

Jeżeli na przykład wiesz, że nie ma cudzysłowów, separator jest zawsze ten sam, a liczba kolumn się nie zmienia, własny parser może być naprawdę prosty i skuteczny.

Lepsze debugowanie i rozwiązywanie problemów

Na koniec warto wspomnieć o rozwiązywaniu problemów. Kiedy coś idzie nie tak z biblioteką csv, zrozumienie podstaw pomaga w debugowaniu. Jeśli wiesz, jak wygląda proces „pod maską”, łatwiej zlokalizować, gdzie leży źródło problemu.

Podsumowując, choć moduł csv jest doskonały, umiejętność ręcznej obsługi plików CSV to cenna kompetencja. Poszerza Twoje horyzonty programistyczne i czyni Cię bardziej wszechstronnym deweloperem, szczególnie gdy pracujesz blisko z danymi tekstowymi.

Czym jest CSV w praktyce – format od podszewki

Zanim przejdziemy do Pythona i konkretów, warto przypomnieć sobie, czym tak naprawdę jest CSV. Sama nazwa to skrót od Comma Separated Values, czyli „wartości oddzielone przecinkami”. I w zasadzie to jest cała idea stojąca za tym formatem.

Plik CSV to zwykły plik tekstowy, w którym:

  • każda linia reprezentuje jeden wiersz danych,
  • wartości w wierszu są oddzielone określonym separatorem (domyślnie przecinkiem),
  • pierwsza linia często zawiera nagłówki kolumn, ułatwiające interpretację danych.

Przykładowa zawartość pliku CSV może wyglądać tak:

id,imie,nazwisko,stanowisko,miasto
1,Anna,Kowalska,Programista,Warszawa
2,Piotr,Nowak,Tester,Kraków
3,Ewa,Wiśniewska,Analityk,Gdańsk

Jak widzisz, format jest banalnie prosty. To właśnie ta prostota sprawiła, że CSV stało się de facto standardem do eksportowania danych z baz danych, arkuszy kalkulacyjnych i wielu innych systemów.

Kluczowe jest zrozumienie, że CSV to po prostu tekst, a Python potrafi ten tekst:

  • czytać,
  • dzielić na fragmenty,
  • konwertować na liczby,
  • łączyć i zapisywać w nowych plikach.

W świecie przetwarzania danych to fundament, który warto dobrze opanować i rozumieć niezależnie od poziomu zaawansowania.

Przykładowy plik: nasz poligon doświadczalny

Aby przykłady były jak najbardziej praktyczne, stworzymy prosty plik CSV, na którym będziemy pracować. Nazwiemy go dane_programistow.csv i założymy, że zawiera informacje o kilku fikcyjnych deweloperach z Polski.

Stwórz plik o nazwie dane_programistow.csv w tym samym katalogu co Twój skrypt Pythona i wklej do niego następującą zawartość:

id,imie,nazwisko,specjalizacja,doswiadczenie_lata,miasto
101,Jan,Kowalski,Python Developer,5,Warszawa
102,Maria,Nowak,Frontend Developer,3,Kraków
103,Paweł,Wiśniewski,DevOps Engineer,7,Gdańsk
104,Anna,Zając,Java Developer,4,Wrocław
105,Krzysztof,Dąbrowski,Mobile Developer,6,Poznań

Mamy tutaj sześć kolumn:

  • id,
  • imie,
  • nazwisko,
  • specjalizacja,
  • doswiadczenie_lata,
  • miasto.

Dane są czytelnie oddzielone przecinkami, a pierwsza linia stanowi nagłówek. To właśnie na tym pliku będziemy ćwiczyć czytanie, konwersję typów, filtrowanie oraz zapis danych.

Ten plik będzie dla nas punktem wyjścia do zrozumienia, jak obsłużyć plik CSV w Pythonie bez bibliotek zewnętrznych, bazując wyłącznie na standardowych możliwościach języka.

Czytanie pliku CSV linia po linii w Pythonie

Teraz przechodzimy do sedna: jak wczytać ten plik CSV do Pythona, nie używając modułu csv? Kluczem jest otwieranie pliku tekstowego i przetwarzanie go linia po linii, a następnie dzielenie tekstu na wartości.

Krok 1: Otwieranie pliku i podstawowe czytanie

Zaczniemy od otwarcia pliku i wyświetlenia zawartości w najprostszy możliwy sposób. W Pythonie warto korzystać z menedżera kontekstu with open(...), który gwarantuje poprawne zamknięcie pliku.

dane_z_csv = []
sciezka_do_pliku = 'dane_programistow.csv'

try:
    with open(sciezka_do_pliku, 'r', encoding='utf-8') as plik:
        for linia in plik:
            print(linia.strip()) # .strip() usuwa białe znaki, w tym znak nowej linii
except FileNotFoundError:
    print(f"Błąd: Plik '{sciezka_do_pliku}' nie został znaleziony.")
except Exception as e:
    print(f"Wystąpił nieoczekiwany błąd: {e}")

W tym przykładzie:

  • open(..., 'r', encoding='utf-8') otwiera plik w trybie odczytu,
  • pętla for linia in plik przechodzi po każdej linii,
  • metoda strip() usuwa białe znaki na początku i końcu, w tym znak nowej linii,
  • obsługujemy potencjalny błąd FileNotFoundError, jeśli plik nie istnieje.

Po uruchomieniu zobaczysz każdą linijkę pliku wydrukowaną w konsoli. To pierwszy krok do ręcznej obsługi CSV – potwierdzenie, że plik jest dostępny i czytelny.

Krok 2: Dzielenie linii na poszczególne wartości

Samo czytanie linii to dopiero początek. Aby sensownie pracować z danymi, potrzebujemy podzielić każdą linię po separatorze, czyli po przecinku. W tym celu skorzystamy z metody split().

dane_z_csv = []
sciezka_do_pliku = 'dane_programistow.csv'

try:
    with open(sciezka_do_pliku, 'r', encoding='utf-8') as plik:
        # Pomiń nagłówek, jeśli chcemy przetwarzać tylko dane
        naglowki = plik.readline().strip().split(',')
        print(f"Nagłówki: {naglowki}")

        for linia in plik:
            wartosci = linia.strip().split(',')
            dane_z_csv.append(wartosci)

    print("\nPrzetworzone dane (bez nagłówków):")
    for wiersz in dane_z_csv:
        print(wiersz)

except FileNotFoundError:
    print(f"Błąd: Plik '{sciezka_do_pliku}' nie został znaleziony.")
except Exception as e:
    print(f"Wystąpił nieoczekiwany błąd: {e}")

Tutaj dzieją się dwie kluczowe rzeczy:

  • Odczyt nagłówków: plik.readline() pobiera pierwszą linię pliku, którą od razu „czyścimy” (strip()) i dzielimy po przecinku na listę nazw kolumn.
  • Przetwarzanie danych: dla każdej kolejnej linii wykonujemy linia.strip().split(',') i dodajemy listę wartości do dane_z_csv.

W efekcie otrzymujesz listę list, gdzie każda wewnętrzna lista odpowiada jednemu wierszowi danych z pliku. To już pełnoprawny, prosty parser CSV, działający bez żadnych zewnętrznych bibliotek.

Programista filtruje i zapisuje dane z pliku CSV w Pythonie, tworząc nowy plik wynikowy bez użycia zewnętrznych bibliotek

Konwersja typów i wygodna reprezentacja danych

Na tym etapie wszystkie wartości z pliku CSV są reprezentowane jako zwykłe stringi. Jeśli chcesz wykonywać operacje numeryczne, na przykład sumować lata doświadczenia, musisz odpowiednie pola przekonwertować na typy liczbowe.

Krok 3: Tworzenie słowników i konwersja pól na liczby

Przykładowy kod, który oprócz dzielenia linii tworzy dla każdego wiersza słownik i konwertuje wybrane kolumny na liczby, może wyglądać tak:

dane_z_csv = []
sciezka_do_pliku = 'dane_programistow.csv'

try:
    with open(sciezka_do_pliku, 'r', encoding='utf-8') as plik:
        naglowki = plik.readline().strip().split(',')

        for linia in plik:
            wartosci_str = linia.strip().split(',')

            # Konwersja wartości - zakładamy, że id i doswiadczenie_lata to liczby
            try:
                # Tworzymy słownik dla każdego wiersza, co jest często wygodniejsze
                wiersz_slownik = {
                    naglowki[0]: int(wartosci_str[0]),  # id
                    naglowki[1]: wartosci_str[1],       # imie
                    naglowki[2]: wartosci_str[2],       # nazwisko
                    naglowki[3]: wartosci_str[3],       # specjalizacja
                    naglowki[4]: int(wartosci_str[4]),  # doswiadczenie_lata
                    naglowki[5]: wartosci_str[5]        # miasto
                }
                dane_z_csv.append(wiersz_slownik)
            except ValueError as ve:
                print(f"Ostrzeżenie: Nie udało się skonwertować wartości w linii '{linia.strip()}': {ve}")
            except IndexError as ie:
                print(f"Ostrzeżenie: Niewłaściwa liczba kolumn w linii '{linia.strip()}': {ie}")

    print("\nPrzetworzone dane (jako lista słowników z typowaniem):")
    for wiersz in dane_z_csv:
        print(wiersz)

    # Przykład operacji na danych: Suma lat doświadczenia
    suma_doswiadczenia = sum(p['doswiadczenie_lata'] for p in dane_z_csv)
    print(f"\nŁączne lata doświadczenia wszystkich programistów: {suma_doswiadczenia}")

except FileNotFoundError:
    print(f"Błąd: Plik '{sciezka_do_pliku}' nie został znaleziony.")
except Exception as e:
    print(f"Wystąpił nieoczekiwany błąd: {e}")

To rozwiązanie ma kilka istotnych zalet:

  • Zamiast listy list pracujesz na liście słowników, co pozwala odwoływać się do danych po nazwie kolumny, np. p['specjalizacja'].
  • Kolumny id oraz doswiadczenie_lata są konwertowane na typ int, dzięki czemu można wykonywać na nich działania arytmetyczne.
  • Potencjalne błędy danych (brak kolumn, błędne typy) są obsługiwane za pomocą bloków try-except, co czyni parser bardziej odpornym.

Na końcu przykład oblicza łączną liczbę lat doświadczenia wszystkich programistów, co pokazuje praktyczne zastosowanie konwersji typów w ręcznej obsłudze pliku CSV w Pythonie.

Tworzenie i zapisywanie nowego pliku CSV

Skoro potrafisz już wczytać i przetworzyć dane z pliku CSV, czas nauczyć się, jak zapisać wyniki swojej pracy do nowego pliku. To częsty scenariusz: czytasz dane, filtrujesz je, a następnie zapisujesz w odseparowanym pliku.

Załóżmy, że chcesz stworzyć plik programisci_seniorzy.csv, który będzie zawierał tylko tych programistów, którzy mają co najmniej 5 lat doświadczenia.

dane_do_zapisu = []
naglowki_do_zapisu = ['id', 'imie', 'nazwisko', 'specjalizacja', 'doswiadczenie_lata', 'miasto']

# Filtrujemy dane z naszej wcześniej przetworzonej listy (dane_z_csv)
for programista in dane_z_csv:
    if programista['doswiadczenie_lata'] >= 5:
        dane_do_zapisu.append(programista)

sciezka_do_nowego_pliku = 'programisci_seniorzy.csv'

try:
    with open(sciezka_do_nowego_pliku, 'w', encoding='utf-8', newline='') as plik_wyjsciowy:
        # Zapisz nagłówki
        plik_wyjsciowy.write(','.join(naglowki_do_zapisu) + '\n')

        # Zapisz wiersze danych
        for programista in dane_do_zapisu:
            # Tworzymy listę wartości w odpowiedniej kolejności
            wartosci_wiersza = [
                str(programista['id']),
                programista['imie'],
                programista['nazwisko'],
                programista['specjalizacja'],
                str(programista['doswiadczenie_lata']),
                programista['miasto']
            ]
            # Łączymy wartości przecinkami i dodajemy znak nowej linii
            plik_wyjsciowy.write(','.join(wartosci_wiersza) + '\n')

    print(f"\nPlik '{sciezka_do_nowego_pliku}' został pomyślnie utworzony.")

except IOError as e:
    print(f"Błąd podczas zapisu pliku '{sciezka_do_nowego_pliku}': {e}")
except Exception as e:
    print(f"Wystąpił nieoczekiwany błąd: {e}")

W tym kodzie warto zwrócić uwagę na kilka szczegółów:

  • Używamy trybu 'w', czyli zapis z nadpisaniem istniejącego pliku. Gdybyś chciał dopisywać dane, skorzystałbyś z trybu 'a'.
  • Parametr newline='' przy otwieraniu pliku jest bardzo ważny, szczególnie w systemach Windows, ponieważ zapobiega pojawianiu się pustych linii pomiędzy rekordami.
  • Funkcja ','.join(...) jest przeciwieństwem split() – łączy listę stringów w jeden tekst, wstawiając między elementy przecinek.
  • Pamiętaj o konwersji wartości liczbowych na stringi przy zapisie, gdyż join() działa wyłącznie na tekstach.

Po wykonaniu tego kodu w katalogu projektowym pojawi się nowy plik programisci_seniorzy.csv zawierający tylko tych deweloperów, którzy spełniają zadany warunek lat doświadczenia.

Typowe problemy i błędy przy ręcznym parsowaniu CSV

Ręczna obsługa plików CSV daje dużą kontrolę, ale wiąże się też z koniecznością myślenia o różnych scenariuszach brzegowych. W prawdziwych projektach pliki z danymi rzadko są idealne, dlatego warto przygotować się na typowe trudności.

Najczęściej spotykane sytuacje problemowe

Oto kilka przykładów problemów, na które możesz natrafić podczas pracy z CSV bez zewnętrznych bibliotek:

  1. Brakujący plik
    Plik, który próbujesz otworzyć, może nie istnieć w podanej lokalizacji. Użycie try-except FileNotFoundError pozwala na eleganckie obsłużenie takiej sytuacji i wyświetlenie czytelnego komunikatu.

  2. Puste linie w pliku
    Czasem pliki CSV zawierają puste linie, zwłaszcza jeśli były ręcznie edytowane. W takim przypadku linia.strip() zwróci pusty string. Przed przetwarzaniem warto sprawdzić:

python if not linia.strip(): # Pomijaj puste linie continue

  1. Niewłaściwa liczba kolumn w wierszu
    Jeżeli w jednej linii jest pięć wartości, a w innej cztery, dostęp do nieistniejącej kolumny spowoduje IndexError. W przykładach pojawia się blok try-except IndexError, który pozwala wykryć takie problemy i np. pominąć wadliwą linię.

  2. Błędne typy danych w kolumnach liczbowych
    Próba skonwertowania napisu „pięć” na int() zakończy się błędem ValueError. Dlatego konwersje do int lub float warto zawsze obejmować w bloki try-except ValueError, jak zostało to pokazane przy tworzeniu słowników.

  3. Inny separator niż przecinek
    Nie wszystkie pliki CSV używają przecinka. W wielu polskich systemach i aplikacjach spotkasz np. średnik jako separator. Wystarczy wtedy zmienić separator w split() na ';', a pozostała logika pozostaje podobna.

  4. Wartości zawierające separator
    To najtrudniejszy przypadek przy ręcznym parsowaniu. Jeśli w danych pojawi się wartość typu "Programista, Junior", proste split(',') uzna przecinek za koniec jednej i początek drugiej kolumny. Standard CSV przewiduje takie sytuacje, stosując cudzysłowy i sekwencje ucieczki, ale ich poprawna obsługa „na piechotę” jest skomplikowana.

Właśnie w takich scenariuszach warto wrócić do modułu csv, który ma wbudowaną, sprawdzoną logikę obsługi cytowań, escape’owania znaków i różnych separatorów.

Świadome podejście do tych problemów i defensywne programowanie sprawia, że Twój kod jest odporniejszy i bezpieczniejszy przy pracy z rzeczywistymi danymi.

Podsumowanie – co daje ręczna obsługa CSV w Pythonie?

Poznałeś pełny proces tego, jak obsłużyć plik CSV w Pythonie bez bibliotek zewnętrznych. Zobaczyłeś, że:

  • CSV to prosty format tekstowy, w którym każdy wiersz i każda kolumna mają swoje miejsce,
  • Python bez modułu csv wciąż świetnie radzi sobie z odczytem, dzieleniem i konwersją danych,
  • możesz zbudować listę słowników, aby wygodnie pracować z danymi po nazwach kolumn,
  • zapis do nowego pliku CSV sprowadza się do łączenia wartości separatorem i właściwego zarządzania nowymi liniami.

Umiejętność ręcznego parsowania CSV daje Ci:

  • lepsze zrozumienie, jak działają dane tekstowe,
  • większą niezależność od dodatkowych bibliotek,
  • możliwość prostego dostosowania logiki do specyficznych wymagań projektu.

W prostych, dobrze sformatowanych plikach CSV taka ręczna obsługa jest całkowicie wystarczająca i bardzo pouczająca. Dla bardziej złożonych przypadków – z niestandardowymi separatorami, wartościami w cudzysłowach czy złożoną strukturą – wbudowany moduł csv zazwyczaj będzie lepszym i bezpieczniejszym wyborem.

Warto jednak znać oba podejścia. Dzięki temu możesz świadomie zdecydować, kiedy postawić na prostą, ręczną obsługę plików CSV w Pythonie, a kiedy skorzystać z bardziej zaawansowanych narzędzi wbudowanych w język.

Marek Radoszewski

Autor

Marek Radoszewski

Freelance developer i tech blogger od 7 lat. Pracował przy projektach dla klientów z Polski, UK i USA. Na blogu pisze o praktycznych aspektach programowania, narzędziach i tym, jak skutecznie rozwijać karierę jako niezależny programista.

Wróć do kategorii Narzędzia i Praktyki