Време је да се вратимо причи о колекцијама започетој прошле суботе. Ако је нисте прочитали, то можете учинити на овом линку, док вам препоручујем да прочитате и чланак о if наредби, јер ћемо је касније користити.

List, tuple и set типови

List, tuple и set представљају контејнере за објекте разних типова података.

List је вероватно најкоришћенији тип колекција који представља уређену групу објеката. Под уређену, мислим на особину листи где сваки објекат има индекс на коме се налази. Листе су промењиве, што значи да можемо додавати нове или уклањати старе елементе. Пример дефинисања нове листе:

my_list = [1, 2, 3, 'Some text', 5.0]
print(my_list)

Испис:

[1, 2, 3, 'Some text', 5.0]

Елементу листе можемо приступити преко индекса. Као што је случај и са стринговима, листе такође подржавају негативно индексирање, односно индекс -1 је последњи члан, -2 претпоследњи итд.

Индекс представља позицију елемента у листи. Индексирање креће од нуле, тако да први елемент има индекс 0, други 1, трећи 2 итд. Последњи елемент има индекс чија је вредност једнака дужини листе – 1. (Ако листа има пет чланова, последњи члан има индекс 4)

my_list = [1, 2, 3, 'Some text', 5.0]
print(my_list[0])  # Први члан
print(my_list[-1])  # Последњи члан, или преко позитивног индекса -> print(my_list[len(my_list)-1])

Испис:

1
5.0

Да бисмо издвојили одређене елементе листе користимо исту синтаксу као код прављења подстринга [start_index:end_index].

my_list = [1, 2, 3, 'Some text', 5.0]

print(my_list[2:4])  # Од трећег до петог

# Ако није наведена једна од граница, узима се крајња вредност
# Ако није наведена са леве стране она је 0
print(my_list[:2])  # Од првог до трећег
# Ако није наведена са десне стране она је дужина листе
print(my_list[2:])  # Од трећег надаље

Испис:

[3, 'Some text']
[1, 2]
[3, 'Some text', 5.0]

Мењање елемента у листи се врши додељивањем нове вредности по индексу. Пример ако желимо заменити други елемент, чији је индекс 1:

my_list = [1, 2, 3, 'Some text', 5.0]

print(f'Стара вредност другог елемента: {my_list[1]}')
my_list[1] = 'Нови други елемент'
print(f'Нова вредност другог елемента: {my_list[1]}')

Испис:

Стара вредност другог елемента: 2
Нова вредност другог елемента: Нови други елемент

Да проверимо да ли постоји неки елемент у листи то можемо урадити помоћу in оператора:

my_list = [1, 2, 3, 'Some text', 5.0]

if 1 in my_list:
    print('my_list има елемент 1!')

# Негација in оператора је not in
if 77 not in my_list:
    print('my_list нема елемент 77!')

Испис:

my_list има елемент 1!
my_list нема елемент 77!

Додавање новог елемента се врши методом append(), а ако додајемо читаву листу то можемо учинити методом extend() или преко + оператора. Брисање елемента можемо учинити помоћу методе remove(), када бришемо преко вредности, или помоћу методе pop(), када бришемо преко индекса.

my_list = [1, 2, 3, 'Some text', 5.0]

my_list.append(6)  # Додавање елемента
print(my_list)

my_list.insert(1, 'Уметнути елемент')  # Уметање елемента на индекс
print(my_list)

my_list.remove('Уметнути елемент')  # Брисање елемента
print(my_list)

my_list.pop(-1)  # Брисање елемента преко индекса
print(my_list)

my_list_2 = ['a', 'b', 'c']
my_list += my_list_2  # Скраћено од my_list = my_list + my_list_2, проширивање листе другом листом (други начин преко методе extend())
print(my_list)

Испис:

[1, 2, 3, 'Some text', 5.0, 6]
[1, 'Уметнути елемент', 2, 3, 'Some text', 5.0, 6]
[1, 2, 3, 'Some text', 5.0, 6]
[1, 2, 3, 'Some text', 5.0]
[1, 2, 3, 'Some text', 5.0, 'a', 'b', 'c']

Још неке занимљиве методе:

my_list = [1, 2, 3, 1, 5, 6, 2]

print(f'Дужина листе је: {len(my_list)}')  # Број елемента у листи
print(f'Елемент 1 се понаваља {my_list.count(1)} пута')  # Број понављања елемента у листи

my_list_copy_1 = my_list  # Додељивање референце, и my_list и my_list_copy_1 указују на исти објекат
my_list_copy_2 = my_list.copy()  # Стварање новог објекта, my_list и my_list_copy_2 указују на различите објекте
print(f'my_list и my_list_copy_1 су исти објекти: {my_list is my_list_copy_1}')
print(f'my_list и my_list_copy_2 су исти објекти: {my_list is my_list_copy_2}')

my_list.clear()  # Брисање сбих елемента
print(my_list)

Испис:

Дужина листе је: 7
Елемент 1 се понаваља 2 пута
my_list и my_list_copy_1 су исти објекти: True
my_list и my_list_copy_2 су исти објекти: False
[]

Tuple (уређена н-торка) је колекција слична листи, с тим да је непромењива (immutable), тј. после иницијализације ју је немогуће мењати. Остале карактеристике су јој мање-више исте као код листе.

my_tuple = (1, 2, 3, 4)

print(f'Први елемент: {my_tuple[0]}')
print(f'Последњи елемент: {my_tuple[-1]}')

print(f'Други и трећи елемент: {my_tuple[1:3]}')

print(f'Елемент 1 се понавља {my_tuple.count(1)} пута')
print(f'Елемент 3 се налази на {my_tuple.index(3)} индексу')

print(f'Елемент 1 се налази у таплу: {1 in my_tuple}')

print(f'Тапл је дужине: {len(my_tuple)}')

# Ako желите направити tuple кога чини само један члан морате додати пратећи зарез
print(f'Са зарезом: {type((1,))}')
print(f'Без зареза: {type((1))}')  # Python ће посматрати заграде као део математичког израза

Set је неуређена колекција (не можемо знати редослед) без дуплих елемента. Она је промењива, док постоји и frozenset који је непромењив.

my_set = {1, 2, 3}
print(my_set)

my_set.add(4)  # Додавање једног елемента
print(my_set)

my_set.update({5, 6, 7})  # Додавање више елемента
print(my_set)

my_set.remove(2)
print(my_set)

print(f'Дужина сета је: {len(my_set)}')

union = {1, 2, 3}.union({3, 4, 5})
print(f'Уније сета {{1, 2, 3}} и {{3, 4, 5}} је: {union}')
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5, 6, 7}
{1, 3, 4, 5, 6, 7}
Дужина сета је: 6
Уније сета {1, 2, 3} и {3, 4, 5} је: {1, 2, 3, 4, 5}

Петље

Поред колекција данас пишем и о петљама. Петље служе да бисмо извршили више истих наредби у одређеном контексту. For петља нам омогућава да то радимо итерирајући кроз неку колекцију, док while петља ће прекинути извршавање кода када услов постане False.

Постоји више облика for петље, најједноставнији је када итерирамо кроз скуп бројева. Пример:

numbers = range(0, 10)  # range() функција нам враћа скуп бројева. Параметри које можемо искористити су почетни број, до ког броја и корак

for i in numbers:
    print(i)

print('*' * 10)

for i in range(0, 10, 2):  # Обратите пажњу да сам сада проследио и корак
    print(i)

print('*' * 10)

for i in range(1, 11, 1):
    print(i)

Испис:

0
1
2
3
4
5
6
7
8
9
**********
0
2
4
6
8
**********
1
2
3
4
5
6
7
8
9
10

Врло лако можемо итерирати и кроз било коју колекцију. Ја ћу кроз следеће примере то учинити са листама, док је исто могуће и са осталим типовима колекција. Приметите у последња два примера како се врши аутоматско распаковање промењивих.

my_list = ['a', 'b', 'c']

for i in my_list:  # Као и над скупом бројева, тако можемо итерирате и над колекцијама
    print(i)

print('-' * 10)

# Ако нам је потребан индекс, за то можемо искористити enumerate() функцију
for index, letter in enumerate(my_list):
    print(f'На индексу {index} се налази слово {letter}')

print('-' * 10)

# У овом случају можемо и рећи enumerate() функцији да крене индексирање од 1
for index, letter in enumerate(my_list, 1):
    print(f'На индексу {index} се налази слово {letter}')

print('-' * 10)

# Оно што enumerate() функција ради јесте пакује две листе у једну листу уређених парова
# То и ми можемо урадити помоћу zip() функције
letters = ['a', 'b', 'c']
numbers = [1, 2, 3]
combined = zip(numbers, letters)
for number, letter in combined:
    print(f'На индексу {number} се налази слово {letter}')

print('-' * 10)

# Могуће је запаковати и више листа те итерирати кроз њих
letters = ['a', 'b', 'c']
numbers = [1, 2, 3]
indexes = [0, 1, 2]
for index, number, letter in zip(indexes, numbers, letters):
    print(f'На индексу {index} налази се број {number} и слово {letter}')

print('-' * 10)

# Овде се дешава аутоматско распаковање. Са десне стране имамо tuple чије вредности распоређујемо на промењиве са леве стране
# тако да прва вредности добија вредност првог члана tuple-а, друга другог итд.

# Погледајмо како заправо један tuple у zip() функцији изгледа
for tuple in zip(indexes, numbers, letters):
    print(tuple)

Испис:

a
b
c
----------
На индексу 0 се налази слово a
На индексу 1 се налази слово b
На индексу 2 се налази слово c
----------
На индексу 1 се налази слово a
На индексу 2 се налази слово b
На индексу 3 се налази слово c
----------
На индексу 1 се налази слово a
На индексу 2 се налази слово b
На индексу 3 се налази слово c
----------
На индексу 0 налази се број 1 и слово a
На индексу 1 налази се број 2 и слово b
На индексу 2 налази се број 3 и слово c
----------
(0, 1, 'a')
(1, 2, 'b')
(2, 3, 'c')

While петља служи како бисмо извршили скуп наредби све док је услов испуњен (True).

number = 0
while number < 6:
    print(number)
    number += 1

print('-' * 10)

# Можемо и намерно завршити петљу пре времена
number = 0
while number < 6:
    print(number)
    if number == 3:
        break  # Искачемо из петље
    number += 1

Испис:

0
1
2
3
4
5
----------
0
1
2
3

И у while и у for петљи можемо искористити резервисану реч continue да прескочимо тренутну итерацију:

for i in range(0, 6):
    if i == 3:
        continue  # Прескачемо тренутну итерацију
    print(i)

print('-' * 10)

i = 0
while i < 6:
    if i == 3:
        i += 1  # Морамо увећати да i не би заувек остало 3 и да не бисмо завршили у бесконачној петљи
        continue  # Прескачемо тренутну итерацију
    print(i)
    i += 1

Испис:

0
1
2
4
5
----------
0
1
2
4
5

map() и filter() функције у Python-у

Да повежемо причу између колекција и петљи. Погледајмо како веома лако можемо имплементирати map функцију у Python језику.

map() функција је често коришћена функција у JavaScript језику, која узима листу и претвара је у нову листу уз примену правила трансформације њених елемената. Нпр. ми ћемо узети листу бројева и претворити је у нову листи тако да она садржи елементе прве листе увећане за 1.

my_list = [1, 2, 3]

my_list = [
    number + 1  # 2. и сваки број увећавамо за један
    for number in my_list  # 1. Пролазимо кроз нашу листу
]

print(my_list)

Испис:

[2, 3, 4]

Могућности овакве синтаксе су многобројне, а ово је само један мали пример.

Filter() функцију имплементирамо на исти начин уз додавање услова по коме филтрирамо.

Filter() функција узима листу, пролази кроз њу и враћа само чланове листе који су задовољили одређен услов. Ми ћемо вратити само парне бројеве.

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

my_list = [
    item  # 3. и враћамо број ако јесте
    for item in my_list  # 1. Пролазимо кроз листу,
    if item % 2 == 0  # 2. проверавамо да ли је остатак при дељењу са 2 нула, односно, да ли је број паран
]

print(my_list)

Испис:

[2, 4, 6, 8, 10]

Толико за данас. Завршили смо причу о колекцијама, док ћу о петљама причати опет за нека два чланка. Овде сам хтео да их поменем како бих могао показати имплементацију map() и filter() функција. Stay Pythonic!


2 коментара

Miroslav · 21. марта 2020. у 22:13

Svaka cast na tutorijalima o Python-u, i hvala. 🙂
Imam jedno pitanje, posto vidim da bi video elemente liste, moras je provuci kroz for petlju. Posto je ista prica i sa nizovimma, pa me zanima da li je u osnovi liste niz? Posto vidim dosta slicnosti izmedju liste i niza. I jedno i drugo imaju indexe, i jedno i drugo moras provuci kroz for petlju, jedino sto kod niza, koliko je meni poznato, kad definises velicinu niza kasnije ne mozes menjati vec moras kreirati novi niz, dok kod liste vidim da je moguce.

    Коста Купрешак · 21. марта 2020. у 23:44

    Поздрав Мирославе, хвала ти! 😊

    Што се тиче низова и листа, разлика је како располажу меморијом.

    Код иницијализације низа задаје се и дужина како си рекао. Тако да се у меморији резервише тачан број места за тај низ, и из тог разлога је непромењив.

    Код листе је нешто другачија прича. Оне су реализоване као динамички низови (https://en.wikipedia.org/wiki/Dynamic_array). Отприлике када се попуни простор, број места низа иза листе се дуплира тако да је обично заузеће нешто веће него што се нама приказује. Имаш сјајну илустрацију на линку изнад. Тако да да, низ ради у позадини, али он није статички, већ динамички.

    У Python-у не постоје класични низови какве можемо пронаћи, у рецимо, C језику, али постоји неки wrapper-и (можеш видети пример на овом линку https://www.programiz.com/python-programming/array).

Затворено за коментаре.