$$ \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \renewcommand{\mod}{\,\mathrm{mod}\,} \renewcommand{\div}{\,\mathrm{div}\,} \newcommand{\metar}{\,\mathrm{m}} \newcommand{\cm}{\,\mathrm{cm}} \newcommand{\dm}{\,\mathrm{dm}} \newcommand{\litar}{\,\mathrm{l}} \newcommand{\km}{\,\mathrm{km}} \newcommand{\s}{\,\mathrm{s}} \newcommand{\h}{\,\mathrm{h}} \newcommand{\minut}{\,\mathrm{min}} \newcommand{\kmh}{\,\mathrm{\frac{km}{h}}} \newcommand{\ms}{\,\mathrm{\frac{m}{s}}} \newcommand{\mss}{\,\mathrm{\frac{m}{s^2}}} \newcommand{\mmin}{\,\mathrm{\frac{m}{min}}} \newcommand{\smin}{\,\mathrm{\frac{s}{min}}} $$

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

7. Филтрирање и претраживање

У овој лекцији чемо видти

  1. Како се филтрирају низови употребом посебне Пајтонове конструкције;
  2. Како се низови података филтрирају "пешке" и зашто важно да и ову вештину поседујемо; и
  3. Како се тражи елемент у низу.

7.1. Филтрирање података употребом Пајтонове конструкције

Филтрирати податке значи из датог низа података издвојити оне који су нам на неки начин интересантни. Програмски језик Пајтон има уграђену конструкцију која омогућује да филтрирамо неки низ података у односу на неки услов.

Филтрирање низа L u odnosu na neki uslov се може постићи конструкцијом која изгледа овако:

[x for x in L if Uslov(x)]

Ова конструкција у нови низ покупи све елементе x низа L који испуњавају Uslov. То је као кад у математици напишемо:

$$ \{x \mid x \in \mathrm{L} \land \mathrm{Uslov}(x) \} $$

Пример. Из следећег низа бројева

In [3]:
A = [-1, 2, 3, 0, -3, 4, -2, -5, 3, 0, 6]

издвојити све позитивне бројеве у један низ

Решење.

In [2]:
[x for x in A if x > 0]
Out[2]:
[2, 3, 4, 3, 6]

Колико низ A има негативних елемената?

In [4]:
len([x for x in A if x < 0])
Out[4]:
4

Пример. Написати Пајтон функцију која из низа стрингова издваја оне који имају највише пет слова.

Решење.

In [13]:
def max_5_slova(L):
    return [s for s in L if len(s) <= 5]

Да видимо како ради ова функција.

In [14]:
max_5_slova(["abrakadabra", "ali", "popokatepetl", "tata", "jabuka", "ja", "biologija", "te", "infomratika", "banana", "volim"])
Out[14]:
['ali', 'tata', 'ja', 'te', 'volim']

Пример. Ево података о једној групи ученика:

In [5]:
razred = [["Ana",     "ž", 13, 46, 160],
          ["Bojan",   "m", 14, 52, 165],
          ["Vlada",   "m", 13, 47, 157],
          ["Gordana", "ž", 15, 54, 165],
          ["Dejan",   "m", 15, 56, 163],
          ["Đorđe",   "m", 13, 45, 159],
          ["Elena",   "ž", 14, 49, 161],
          ["Žaklina", "ž", 15, 52, 164],
          ["Zoran",   "m", 15, 57, 167],
          ["Ivana",   "ž", 13, 45, 158],
          ["Jasna",   "ž", 14, 51, 162]]

За сваког ученика је наведено име, пол, старост (у годинама), маса (у килограмима) и висина (у центиметрима).

Направи нови низ кога чине само дечаци.

In [6]:
[ucenik for ucenik in razred if ucenik[1] == "m"]
Out[6]:
[['Bojan', 'm', 14, 52, 165],
 ['Vlada', 'm', 13, 47, 157],
 ['Dejan', 'm', 15, 56, 163],
 ['Đorđe', 'm', 13, 45, 159],
 ['Zoran', 'm', 15, 57, 167]]

Направи нови низ кога чине само девојчице које имају 13 или 14 година.

In [9]:
[ucenik for ucenik in razred if ucenik[1] == "ž" and (ucenik[2] == 13 or ucenik[2] == 14)]
Out[9]:
[['Ana', 'ž', 13, 46, 160],
 ['Elena', 'ž', 14, 49, 161],
 ['Ivana', 'ž', 13, 45, 158],
 ['Jasna', 'ž', 14, 51, 162]]

7.2. Филтрирање података "пешке"

Сада ћемо показати како се из низа података могу издвојити елементи који задовољавају неки услов, али овај пут без употребе специјалне Пајтонове конструкције [x for x in L if Uslov(x)] коју смо користили у претходном одељку.

Идеја је једноставна:

  1. направимо нови празан низ који ће бити помоћни низ; он ће временом акумулирати све елементе низа који задовољавају наведени услов;
  2. for циклусом прођемо кроз низ; и
  3. елементе који задовољавају наведени услов додамо на помоћни низ.

Пример. Написати Пајтон функцију izdvoj_pozitivne која из датог низа бројева издваја све позитивне бројеве.

Решење.

In [18]:
def izdvoj_pozitivne(L):
    rez = []
    for x in L:
        if x > 0:
            rez.append(x)
    return rez

Неколико коментара:

  1. наредба rez = [] поставља помоћни низ rez на празан низ, који се означава овако: [];
  2. наредба rez.append(x) на крај низа rez додаје x као нови елемент .

Да видимо како функција ради

In [20]:
izdvoj_pozitivne([-1, 2, 3, 0, -3, 4, -2, -5, 3, 0, 6])
Out[20]:
[2, 3, 4, 3, 6]

Када филтрирање напишемо "пешке" то нам омогућује да лако решимо неке проблеме које иначе не бисмо брзо и елегантно могли да решимо употребом уграђене Пајтонове конструкције за филтрирање.

Пример. Написати Пајтон функцију pozicije_pozitivnih која за дати низ бројева враћа индексе елемената који су позитивни.

Режење.

In [22]:
def pozicije_pozitivnih(L):
    i = -1
    rez = []
    for x in L:
        i += 1
        if x > 0:
            rez.append(i)
    return rez

Видимо да ова функција комбинује идеју филтрирања и бројач.

  1. Прво помоћни низ поставимо на празан низ, а бројач на -1 (зашто?).
  2. У сваком пролазу кроз for циклус увећамо бројач за један и ако је одговарајући елемент низа позивитан, на крај помоћног низа додамо i, што је "кућни број" кућице за коју смо управо утврдили да је позитивна.

Да видимо како ова функција ради:

In [23]:
pozicije_pozitivnih([-1, 2, 3, 0, -3, 4, -2, -5, 3, 0, 6])
Out[23]:
[1, 2, 5, 8, 10]

7.3. Тражење елемента у низу

Веома често је потребно проверити да ли се неки елемент налази у низу, и ако се налази у низу, на ком месту се јавља.

У Пајтону је веома лако проверити да ли се неки елемент налази у низу користећи уграђени оператор in. Ево примера. Нека је A следећи низ:

In [2]:
A = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Ако желимо да проверимо да ли се број 20 јавља у низу A то можемо учинити овако:

In [3]:
20 in A
Out[3]:
False

Систем је вратио False (енгл. "нетачно"), што значи да се број 20 не налази у низу A. С друге стране,

In [4]:
19 in A
Out[4]:
True

Овај пут је систем вратио True (енгл. "тачно") зато што се број 19 налази у низу A.

Ако желимо да одредимо где се у низу налази прво појављивање неког елемента написаћемо функцију која то ради за нас. Функција prvo_pojav(x, L) тражи прво појављивање елемента x у низу L. Ако се елемент x не јавља у низу L функција враћа -1.

In [6]:
def prvo_pojav(x, L):
    i = -1
    for y in L:
        i += 1
        if y == x: return i
    return -1

Ова функција користи бројач како би знала редни број елемента кога упоређује са x.

  1. Прво бројач поставимо на -1 (зашто?).
  2. У сваком пролазу кроз for циклус увећамо бројач за један и ако је одговарајући елемент низа једнак са x вратимо вредност бројача, што је позиција првог појављивања елемента x у низу L.
  3. Ако се for циклус заврши, то значи да нисмо нашли елемент x у низу L па функција враћа -1.

Ево примера. Нека је

In [7]:
B = ["ovo", "ono", "oko", "oro", "era", "rad", "dar", "oko", "era", "ono"]

Тада је

In [9]:
prvo_pojav("oko", B)
Out[9]:
2

док је

In [11]:
prvo_pojav("iva", B)
Out[11]:
-1

зато што се стринг "iva" не јавља у низу B.

Функција posl_pojav(x, L) тражи последње појављивање елемента x у низу L. Ако се елемент x не јавља у низу L функција враћа -1.

In [12]:
def posl_pojav(x, L):
    i = -1
    n = -1
    for y in L:
        i += 1
        if y == x: n = i
    return n

Ова функција користи бројач i како би знала редни број елемента кога упоређује са x, као и променљиву n у којој памти позицију последњег појављивања елемента x у делу низа кога смо до тог тренутка прегледали.

  1. У сваком пролазу кроз for циклус увећамо бројач за један и ако је одговарајући елемент низа једнак са x вредност бројача упишемо у променљиву n.
  2. Када се for циклус заврши променљива n саржи позицију последњег појављивања елемента x у низу L, што вратимо као резултат рада функције.
  3. Ако се елемент x не појављује у низу L вредност променљиве n ће остати -1, па то и вратимо као резултат рада.

Ево примера.

In [14]:
posl_pojav("oko", B)
Out[14]:
7
In [16]:
posl_pojav("rad", B)
Out[16]:
5
In [17]:
posl_pojav("iva", B)
Out[17]:
-1

7.4. Задаци

Задатак 1. Нутритивни подаци за неке рибе и морске плодове су дати у следећој табели:

Намирница (100г) Енергетска вредност (kcal) Угљени хидрати (г) Беланчевине (г) Масти (г)
Туна 116 0 26 1
Ослић 88 0 17.2 0.8
Пастрмка 119 0 18 5
Лосос 116 0 20 3.5
Скуша 205 0 19 14
Сардине 135 0 18 5
Харинга 158 0 18 9
Бакалар 82 0 18 0.7
Сом 95 0 16.4 2.8
Шаран 127 0 17.6 5.6
Орада 115 0 16.5 5.5
Јегуља 184 0 18.4 11.7
Шкампи 106 1 20 2
Дагње 86 4 12 2
Козице 71 1 13 1
Лигње 92 3 15.6 1.3
Хоботница 81 0 16.4 0.9
Јастог 112 0 20 1.5

Подаци из табеле су представљени листом у ћелији испод:

In [10]:
morski_plodovi = [
  ["Туна", 116, 0, 26, 1],
  ["Ослић", 88, 0, 17.2, 0.8],
  ["Пастрмка", 119, 0, 18, 5],
  ["Лосос", 116, 0, 20, 3.5],
  ["Скуша", 205, 0, 19, 14],
  ["Сардине", 135, 0, 18, 5],
  ["Харинга", 158, 0, 18, 9],
  ["Бакалар", 82, 0, 18, 0.7],
  ["Сом", 95, 0, 16.4, 2.8],
  ["Шаран", 127, 0, 17.6, 5.6],
  ["Орада", 115, 0, 16.5, 5.5],
  ["Јегуља", 184, 0, 18.4, 11.7],
  ["Шкампи", 106, 1, 20, 2],
  ["Дагње", 86, 4, 12, 2],
  ["Козице", 71, 1, 13, 1],
  ["Лигње", 92, 3, 15.6, 1.3],
  ["Хоботница", 81, 0, 16.4, 0.9],
  ["Јастог", 112, 0, 20, 1.5]]

Из ове табеле издвој оне намирнице које не садрже угљене хидрате и имају мање од 10 г масти на 100 г намирнице.

In [ ]:
 

Задатак 2. Ученици једног разреда су скакали у даљ. Сваки ученик је скакао три пута и резултати су дати у ћелији испод:

In [11]:
takmicari = [["Алексић Алекса", 4.25, 4.31, 4.22],
             ["Бранковић Бранко", 3.89, 4.02, 4.05],
             ["Вуковић Вук", 0, 3.91, 4.1],
             ["Гавриловић Гаврило", 3.78, 3.26, 3.11],
             ["Дејановић Дејан", 4.56, 4.31, 4.27],
             ["Ђорђевић Ђорђе", 4.63, 4.6, 4.52],
             ["Жарковић Жарко", 3.47, 3.51, 3.58],
             ["Зорић Зоран", 4.12, 4.15, 4.09],
             ["Ивановић Иван", 3.91, 3.26, 0],
             ["Јовановић Јован", 4.01, 4.1, 4.12],
             ["Костић Коста", 3.51, 3.72, 3.41],
             ["Лукић Лука", 2.15, 2.17, 2.18],
             ["Марковић Марко", 3.39, 0, 3.26],
             ["Ненадовић Ненад", 4.25, 4.18, 4.22],
             ["Огњановић Огњен", 4.31, 4.26, 4.12],
             ["Петровић Петар", 4.23, 4.34, 4.34],
             ["Ракић Рака", 3.51, 3.54, 3.62],
             ["Станојевић Станоје", 4.57, 4.59, 4.63]]

Издвој из табеле оне редове који садрже ученике који су начинили бар један преступ. Преступ је у табели означен тако што је дужина одговарајућег скока постављена на 0.

In [ ]:
 

Задатак 3. У наредној ћелији се налазе подаци о неколико ученика. За сваког ученика је наведено његово презиме, име, ЈМБГ, пол, разред који похађа и просек на крају тог разреда:

In [12]:
podaci = [
    ["Петровић",  "Петар", "0308003800019", "м", 8, 4.52],
    ["Јаснић",    "Јасна", "1210003805026", "ж", 8, 5.00],
    ["Аничић",    "Аница", "1105004805019", "ж", 7, 4.11],
    ["Веснић",    "Весна", "2901005705011", "ж", 6, 5.00],
    ["Ђорђевић",  "Ђорђе", "1504005700012", "м", 6, 3.12],
    ["Милошев",   "Милош", "1506004400056", "м", 7, 2.51],
    ["Милошев",   "Петар", "1506004400057", "м", 7, 2.48],
    ["Ненадовић", "Ненад", "2109003800046", "м", 8, 3.58],
    ["Ненадовић", "Јасна", "2109003805021", "ж", 8, 4.21]]

(а) Направи нову табелу коју чине само ученици осмог разреда.

In [ ]:
 

(б) Направи нову табелу коју чине само врло добри ученици.

In [ ]:
 

(в) Направи нову табелу коју чине само дечаци који нису одлични.

In [ ]:
 

Задатак 4. Написати функцију nadji_sve(x, L) која враћа низ са позицијама свих појављивања елемента x у низу L.

In [ ]:
 

Задатак 5. Написати Пајтон функцију ima_zbir_tri(L) која провери да ли постоје три елемента низа L са особином да је збир нека два од њих једнак оном трећем.

In [ ]:
 

Задатак 6. Написати Пајтон функцију presek(L, M) која враћа низ свих елемената који се јављају и у низу L и у низу M.

In [ ]:
 

Задатак 7. Написати Пајтон функцију razlika(L, M) која враћа низ свих елемената који се јављају у једном од ова два низа, а не јављају се у другом.

In [ ]: