Python: informacje wybrane. Kiedyś myślałem że będę opisywał dla siebie i potomnych elementy i składnię pythona. Ale potem pojawił się Jetbrains Academy i przestało mieć to sens. Pozbierałem i zarchiwizowałem tutaj wszystkie swoje stare notatki ,ale jeżeli potrzebuje dowiedzieć się czegoś w szczegółach to zaglądam do JetBrains Academy.
enumerate(), zip()
enumerate() - funkcja przyjmuje na wejściu listę, zwraca też listę, składająca się z elementów tuple
. Każdy tuple
składa z dwóch elementów (pierwszy to indeks bieżącego elementu, drugi to oryginalna wartość)
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
list(enumerate(seasons))
# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
Szybkie generowanie słownika:
dict( enumerate(['red', 'blue', 'green']) )
# {0: 'red', 1: 'blue', 2: 'green'}
for (indeks, element) in enumerate(kolekcja):
# kod pętli for
zip() - funkcja używana w pętli for; daje nam elementy z tej samej pozycji w kilku kolekcjach; gdy kolekcje są różnej długości, wielkość najkrótszej kolekcji będzie brana przy ilości powtórzeń pętli
for (element_a, element_b) in zip(kolekcja_a, kolekcja_b):
# kod pętli
Tuple, list, dict
Nawiasy okrągłe (...)
Tuple (1, 2, 3)
- jest typem niezmiennym, raz zdefiniowanego nie można zmienić.
Definiowanie tuple:
my_tuple = (0, 1, 2)
tuple1 = ("raz", "dwa", "trzy")
# tuple1[0] = "jeden" – spowoduje błąd
Rozpakowanie tuple:
tuple1 = ("raz", "dwa", "trzy")
x, y, z = tuple1
print(x) # >>> "raz"
print(y) # >>> "dwa"
print(z) # >>> "trzy"
To co z tuple robi tuple to przecinek:
not_a_tuple = ('cat') # <class 'str'>
now_a_tuple = ('cat',) # <class 'tuple'>
weekend = 'Saturday', 'Sunday'
print(type(weekend)) # <class 'tuple'>
empty_tuple = tuple()
print(type(empty_tuple)) # <class 'tuple'>
Tuples are faster and more memory-efficient than lists.
Nawiasy kwadratowe [...]
Listy [1, 2, 3]
, dostęp do poszczególnych elementów w list
czy tuple
odbywa się za pomocą indeksów: my_list[0]
lub my_tuple[0]
Definiowanie list:
my_list= [4, 5, 5, 3, 4]
list = [1, 2, 3]
list2 = ["kwiatek", "doniczka", "ziemia", "woda"]
list3 = []
list4 = [1, "dwa", 3, 4]
list5 = list(range(2,5))
Możemy indeksować, slice’ować. Do elementu odwołujemy się przez indeks.
Sposoby na manipulacje listami:
L[i], L[i:j], L[i:j:k]
len(), min(), max(), del(L[i])
L.append(), L.extend(), L.count(), L.index(), L.insert(),
L.pop(), L.remove(), L.reverse(), L.sort()
Listy zagnieżdżone:
lista = [[1,2,3],[4,5,6],[7,8,9]]
lista = [[1,2,3],
[4,5,6],
[7,8,9]]
lista[1][2] => 6
Jeśli przypiszemy listę do innej zmiennej to tak naprawdę przypiszemy adres w pamięci do listy możemy użyć kopiowania list:
nowa_lista = lista.copy()
nowa_lista = list(stara_lista)
nowa_lista = stara_lista[:]
Do głębokiego kopiowania (kopiowanie wszystkiego jako wartość) używamy modułu copy i metody deepcopy()
import copy
nowy = copy.deepcopy(stary)
Set
Unordered collection of distinct hashable objects.
https://www.programiz.com/python-programming/set
Nawiasy klamrowe {...}
Słownik: {'key': 'value'}
- odwołujemy się poprzez klucz a nie indeks:
x = {"nazwisko":"kowalski", "pesel":88120134567}
x['pesel']
klucz – musi być typem niezmiennym (string, tuple, liczba), musi być unikalny (tylko jeden w słowniku)
wartość – mogą być powtórzone
Przykład słownika:
my_dict = {
'Jan': 4,
'Adam': 5,
'Ania': 5,
'Adrian': 3,
'Agnieszka': 4
}
osoby = {"studenci":["Ala", "Jan", "Ania"], "wykladowcy":["doktor", "profesor"]}
print(osoby["studenci"][1])
osoby["wykladowcy"].append("magister")
osoby["administracja"] = ["pani Basia z dziekanatu"]
osoby.update({"ochrona":"Impel"})
print(osoby.keys)
print(osoby.values)
for key, item in osoby.items():
print(key, item)
Definiowanie pustego słownika
testable = {}
testable['key'] = 'value'
print(testable['key']) # value
- random_dict.keys() - [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
- random_dict.values() - [‘20’, ‘40’, ‘60’, ‘80’, ‘100’]
- random_dict.items() - [(‘a’, ‘20’), (‘b’, ‘40’), (‘c’, ‘60’), (‘d’, ‘80’), (‘e’, ‘100’)]
# get method does not throw an error
print(testable.get('key')) # value
print(testable.get('not_a_key')) # None
testable = {'key1': 'value1', 'key2': 'value2'}
del testable['key1'] # this will remove both the key and the value from dictionary object
print(testable) # {'key2', 'value2'}
del testable['not_a_key'] # throws a KeyError
del testable['key1'] # throws a KeyError as we've already deleted the object by the key
del testable # deletes the whole dictionary
catalog = {'green table': 5000, 'brown chair': 1500, 'blue sofa': 15000, 'wardrobe': 10000}
print('blue sofa' in catalog) # True
print('yellow chair' in catalog) # False
List Comprehension
Służą do transformacji jednej listy na inną listę (tworzenie nowych list według określonych zasad): Klasyczna pętla:
liczby = [2,3,4]
liczby3 = []
for i in liczby:
if i > 0:
liczby3.append(i**3)
liczby3
List comprehension:
liczby3 = [i**3 for i in liczby if i >0 ]
liczby3
Jeszcze jedne przykład:
# prosty sposób:
kwadraty = []
for x in range(20, 39):
kwadraty.append(x)
# List comprehension
kwadraty = [x for x in range(20, 39)]
Składnia
[output expression for item in iterable]
# Exponentiation - all items from list
numbers = [1, 2, 3, 4, 5]
squares = [number**2 for number in numbers]
print(squares)
można dodać również warunek if:
[output expression for item in iterable if condition]
# Exponentiation - even items only
numbers = [1, 2, 3, 4, 5]
squares = [number**2 for number in numbers if number > 2]
print(squares)
[output expression if-else clause for item in iterable condition/s on iterable]
numbers = [1, 2, 3, 4, 5, 6, 18, 20]
squares = [
"small" if number < 10 else "big"
for number in numbers
if number % 2 == 0
if number % 3 == 0]
print(squares)
List comprehension są wydajniejsze od pętli for, zapis jest bardziej zwarty
arg
Operator * przekazuje do funkcji po jednym argumencie z listy:
args = [1, 2]
my_func(*args)
Można to rozpisać jako:
args = [1, 2]
my_func(args[0], args[1])
Pozwala przekazywać większą ilość argumentów do funkcji:
def add(a, b, *args):
total = a + b
for n in args:
total += n
return total
# The length of `args` is 3
print(add(1, 2, 3, 4, 5))
# The length of `args` is 0
print(add(1, 2))
def will_survive(*names):
for name in names:
print("Will", name, "survive?")
will_survive("Daenerys Targaryen", "Arya Stark", "Brienne of Tarth")
print(*"fun") # f u n
print(*[5, 10, 15]) # 5 10 15
kwarg
Dla słowników używamy zapisu z dwoma gwiazdkami ** (ang. keyword argument)
xgb_params = {
'max_depth' : 5,
'n_estimators' : 100,
'learning_rate' : 0.3,
'random_state' : 0
}
model = xgb.XGBRegressor(**xgb_params)
Notice the difference: *args
provides access to a tuple of remaining values, while **kwargs
collects remaining key-value pairs in a dictionary.
Funkcja Lambda
Funkcja nie posiadająca nazwy, o zwartym zapisie stosowana do prostych zadań. Przykład:
f = lambda x: x * x
Może być zapisana wyłącznie w jednej linijce i może zawierać tylko jedno wyrażenie
Map()
Przekazuje do funkcji element listy jako argument. Wynik działania funkcji jest zwracany jako element nowej listy
# map(function, element_iterowalny)
map(function, iterable, ...)
Krok po kroku:
-
pobranie elementu z listy
-
przekazanie go do funkcji jako argument
-
funkcja coś z nim robi (np. mnoży razy dwa) i zwraca wynik
-
wynik, który zwraca przekazuje do nowej listy
Przykład:
numbers = [7, 4, 9, 6, 8, 1]
def double(items):
output = []
for val in items:
output.append(val * 2 )
return output
result = double(numbers)
print(result)
Odpowiednik powyższego kodu z wykorzystaniem map()
:
def double(value):
return value * 2
numbers = [7, 4, 9, 6, 8, 1]
result = list(map(double, numbers))
print(result)
Apply
Umożliwia razem z funkcją lambda
szybkie iterowanie po kolumnach dataframe:
df['GPS y'] = df['GPS y'].apply(lambda x : dms2dd(x))
Jeżeli chcemy przekazać do funkcji kilka argumentów (z jednego wiersza Pandas DataFrame):
df['newcolumn'] = df.apply(lambda x: fxy(x['A'], x['B']), axis=1)
Generators
Przykład generatora: range(10)
. Wartości są generowano dopiero wtedy gdy są potrzebne l = list(range(10))
Inny przykład:
def gen(n): # an infinite sequence generator that generates integers >= n
while True:
yield n
n += 1
G = gen(3) # starts at 3
print(next(G)) # 3
print(next(G)) # 4
print(next(G)) # 5
print(next(G)) # 6
Iterators
# This is a list...
my_list = [1, 2, 3]
# ... and this is how we create an iterator from it
my_iterator = iter(my_list)
print(my_iterator) # <list_iterator object at 0x000001F06D792B70>
print(next(my_iterator)) # 1
print(next(my_iterator)) # 2
print(next(my_iterator)) # 3
print(next(my_iterator)) # StopIteration exception
Python dla pętli for
automatycznie utworzy iterator z danego obiektu iterowalnego i będzie otrzymywał jego elementy jeden po drugim za pomocą metody next
, aż do wyczerpania obiektu iterowalnego.
for item in my_list:
print(item)
# 1
# 2
# 3
for element in characters:
print(element)
# or
print(*characters)
zip()
Iterator dla kilku elementów iterowalnych:
short_list = [1, 2, 3]
long_list = [10, 20, 30, 40]
for a, b in zip(short_list, long_list):
print(a, b)
# 1 10
# 2 20
# 3 30
enumerate()
months_list = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
for n, month in enumerate(months_list):
print(n + 1, month)
# 1 Jan
# 2 Feb
# 3 Mar
# 4 Apr
# 5 May
# 6 Jun
# etc.
String - podstawowe operacje
text.lower()
- wszystkie litery z małej
text.upper()
- wszystkie litery z małej
text.title()
- wszystkie wyrazy z dużej
text.strip()
- usunięcie białych znaków z końca i początku
text.split(' ')
- podział tekstu (spacja)
" ".join(words)
- łączenie wyrazów
'80,5'.replace(',', '.')
- zamiana znaków
ord()
- zwraca numer Unicode pojedynczego znaku
chr()
- zwraca znak na podstawie numeru Unicode
Numerowanie znaków
str = "Python"
P | y | t | h | o | n |
---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 |
-6 | -5 | -4 | -3 | -2 | -1 |
str[3] #h
str[:3] #Pyth
str[-1] #n
str[4:] #on
str[-4:-2] # th
str[::-1] #nohtyP
Multiline string
Definiujemy jako potrójny apostrof'''
lub cudzysłów """
create_users = """
INSERT INTO
cars (offer_id,city,region,model,year,mileage,fuel_type,displacement,price,currency,pub_date,duration,end_price)
VALUES
(6069449316,'Prudnik','Opolskie','Toyota Yaris II',2009,153000,'Diesel',-1,12999,'PLN','2019-12-31',7,12999),
(6068202189,'Włocławek','Kujawsko-pomorskie','Toyota Yaris II',2008,110000,'Benzyna',1298,17600,'PLN','2019-12-31',21,16900),
(6067206317,'Łódź','Łódzkie','Toyota Yaris II',2010,167938,'Diesel',1364,13999,'PLN','2019-12-31',31,13900),
(6069421596,'Katowice','Śląskie','Toyota Yaris II',2008,214548,'Benzyna+LPG',1298,12000,'PLN','2019-12-31',31,12000),
(6068568066,'Katowice','Śląskie','Toyota Yaris II',2007,38000,'Benzyna',1298,19300,'PLN','2019-12-31',12,18500);
"""
Wtedy można dowolnie łamać ciąg znaków
Zapis bardzo długi stringów z wykorzystaniem nawiasu
# long string
str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
# use brackets to breake lines
str2 = ('ssssssssss'
'ssssssssssssss'
'ssssssssssss')
f-string
String formatujący f'string'
(Python >= 3.6)
name = "Eric"
age = 74
f"Hello, {name}. You are {age}."
> 'Hello, Eric. You are 74.'
Opcje dostępne przed Python 3.6:
name = 'Alan'
age = 53
string = 'Hello, {name}. You are {age}.'.format(name = name, age = age)
print(string)
name = 'Greg'
age = 17
string = 'Hello, {0}. You are {1}.'.format(name, age)
print(string)
name = 'George'
age = 27
string = 'Hello, {}. You are {}.'.format(name, age)
print(string)
Więcej: Python 3’s f-Strings: An Improved String Formatting Syntax (Guide)
Formatowanie : Using % and .format() for great good!
Pliki tekstowe
Otwarcie pliku:
plik = open("scieżka_do_pliku", tryb, encoding="utf-8")
tryby:
- r – tylko do odczytu
- w – zapisywanie pliku (stary plik o tej samej nazwie będzie usunięty)
- r+ - do odczytu i zapisu
- a – dopisywanie do pliku (dane są dopisane do końca istniejącego pliku)
plik.read() – odczytanie całego pliku, zwracany jest string zawierający cały tekst pliku (włącznie ze znakami \n) – opc. argument – int określająca ilość bajtów do wczytania plik.readline() – odczytanie jednej linii z pliku, zwracany jest string z linijką testu, włącznie ze znakiem \n plik.readlines() – odczytuje cały tekst – zwraca listę stringów - linijek
for line in plik:
print(line, end='')
Pliki należy zamykać po użyciu:
plik = open("plik.txt")
# kod
plik.close()
Otwarcie pliku za pomocą with pozwala na automatyczne zamykanie pliku przez Pythona
with open("plik.txt", encoding="utf-8") as plik:
print(plik.readline())
Context manager:
# invoking a context manager
with statement as variable_name:
...
plik.write(string) – zapisuje string do pliku w obecnej pozycji kursora, zwraca liczbę zapisanych znaków – należy pamiętać o znaku \n
plik.writelines(iterable) – zapisuje elementy z kolekcji jako poszczególne linie w pliku
Plik musi być otworzony w trybie do zapisu aby móc go zmieniać!
TODO
str() vs repr() in Python
output of the __str__
should be highly readable and the output of the __repr__
should be unambiguous. In other words, __str__
creates a representation for users and __repr__
creates a representation for developers.
A good rule is to always define the __repr__
method first since it is the method used by developers in debugging. It is also a fallback method for __str__
which means that if the __str__
method isn’t defined, in the situations where it’s needed, the __repr__
will be called instead.
stdin, stdout, stderr vs print()
try:
except
sys.stderr.write(‘’)