ლექცია 11 · XI კვირაLecture 11 · Week XI

სიმრავლე და
ლექსიკონი
Sets and
dictionaries

set · dict · შესაბამის სტრუქტურებთან სამუშაო ფუნქციები set · dict · the methods that come with them

დღეს ასევე: პრაქტიკული დავალება #3 Also today: practical assignment #3

გამეორება · ლექციები 09–10Review · lectures 09–10

შემოწმება — 9 კითხვაCheck yourself — 9 questions

1. რა განსხვავებაა "w" და "a" რეჟიმებს შორის? 1. What is the difference between modes "w" and "a"?
"w" ფაილის შიგთავსს შლის და ახლიდან წერს; "a" არსებულს ინახავს და ბოლოში ამატებს. "w" erases the file and writes from scratch; "a" keeps what is there and appends at the end.
2. რატომ ვწერთ encoding="utf-8"? 2. Why do we write encoding="utf-8"?
Windows-ზე ნაგულისხმევი კოდირება UTF-8 არაა, ამიტომ ქართული ტექსტი ან „კუბიკებად“ გამოჩნდება, ან UnicodeDecodeError-ს გამოიწვევს. On Windows the default encoding is not UTF-8, so non-ASCII text either shows up as boxes or raises a UnicodeDecodeError.
3. რა უპირატესობა აქვს with open(...) as f:-ს? 3. What is the advantage of with open(...) as f:?
ფაილს ავტომატურად ხურავს ბლოკიდან გამოსვლისას — მაშინაც კი, თუ შიგნით შეცდომა მოხდა. It closes the file automatically on leaving the block — even if an error occurred inside.
4. რას დაბეჭდავს? a = [1,2]; b = a; b.append(3); print(a) 4. What does this print? a = [1,2]; b = a; b.append(3); print(a)
[1, 2, 3]. b = a ასლს არ ქმნის — ორივე სახელი ერთსა და იმავე სიაზე მიუთითებს. ასლისთვის: a.copy() ან a[:]. [1, 2, 3]. b = a does not copy — both names point at the same list. For a copy use a.copy() or a[:].
5. რას აბრუნებს lst.sort()? 5. What does lst.sort() return?
None — ის ორიგინალს ცვლის ადგილზე. ახალი დახარისხებული სიისთვის — sorted(lst). None — it sorts in place. For a new sorted list use sorted(lst).
6. რა განსხვავებაა append([3,4])-სა და extend([3,4])-ს შორის? 6. What is the difference between append([3,4]) and extend([3,4])?
append მთელ სიას ერთ ელემენტად დაამატებს → [1,2,[3,4]]; extend ელემენტებს ცალ-ცალკე → [1,2,3,4]. append adds the whole list as one element → [1,2,[3,4]]; extend adds the elements individually → [1,2,3,4].
7. რით განსხვავდება tuple list-ისგან? 7. How does a tuple differ from a list?
tuple უცვლელია — შექმნის შემდეგ ელემენტს ვერ შეცვლი/დაამატებ. სამაგიეროდ ოდნავ სწრაფია და ლექსიკონის გასაღებად გამოდგება. A tuple is immutable — you cannot change or add elements after it is created. In exchange it is slightly faster and can serve as a dictionary key.
8. რას აკეთებს enumerate() და zip()? 8. What do enumerate() and zip() do?
enumerate ერთდროულად აბრუნებს ინდექსსა და მნიშვნელობას; zip ორ (ან მეტ) თანმიმდევრობას პარალელურად გადის, წყვილებად. enumerate yields the index and the value together; zip walks two (or more) sequences in parallel, as pairs.
9. რატომ არის [[0]*3]*3 საშიში? 9. Why is [[0]*3]*3 dangerous?
ის სამ მიმართვას ერთსა და იმავე სიაზე ქმნის — ერთი ელემენტის შეცვლა სამივე „რიგს“ შეცვლის. სწორია: [[0]*3 for _ in range(3)]. It creates three references to the same list — changing one element changes all three “rows”. The correct form is [[0]*3 for _ in range(3)].

ახალი ტიპიA new type

set — სიმრავლეset — a set

უნიკალური ელემენტების დაულაგებელი კრებული.

An unordered collection of unique elements.

s = {1, 2, 3, 3, 2, 1}
print(s)                  # {1, 2, 3} — duplicates gone

empty = set()             # ⚠ {} — that is a dictionary!

numbers = [1, 2, 2, 3, 3, 3]
unique = set(numbers)
print(unique)             # {1, 2, 3}
print(list(unique))       # [1, 2, 3] — back to a list

print(len(s))             # 3
print(2 in s)             # True
# print(s[0])             # TypeError — no indexing!
#1 გამოყენებადუბლიკატების მოშორება ერთ ხაზში: list(set(data)). Use #1Removing duplicates in one line: list(set(data)).
#2 გამოყენებაin-შემოწმება ბევრად სწრაფია, ვიდრე სიაში — დიდ მონაცემზე ეს კრიტიკულია. Use #2An in check is far faster than on a list — critical for large data.

set

სიმრავლეთა ოპერაციებიSet operations

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a | b)    # {1,2,3,4,5,6}  union         a.union(b)
print(a & b)    # {3, 4}         intersection  a.intersection(b)
print(a - b)    # {1, 2}         difference    a.difference(b)
print(a ^ b)    # {1,2,5,6}      symmetric difference

print({1, 2} <= a)     # True — is it a subset?
print(a.isdisjoint({9}))   # True — nothing in common

ცვლილებაModifying

s = {1, 2, 3}
s.add(4)              # one element
s.update([5, 6])      # several
s.discard(10)         # remove — no error if absent
s.remove(1)           # remove — KeyError if absent
x = s.pop()           # an arbitrary element
s.clear()
პრაქტიკული მაგალითიორ ჯგუფში საერთო სტუდენტები: group_a & group_b. მხოლოდ პირველში მყოფნი: group_a - group_b. A practical exampleStudents in both groups: group_a & group_b. Only in the first: group_a - group_b.

ახალი ტიპიA new type

dict — ლექსიკონიdict — a dictionary

წყვილები გასაღები → მნიშვნელობა. წვდომა ინდექსით კი არა, სახელით.

Key → value pairs. You look things up by name, not by index.

student = ["ნინო", 20, 92]
print(student[2])     # what is 2?
student = {
    "name": "ნინო",
    "age": 20,
    "score": 92,
}
print(student["score"])   # 92
empty = {}
also = dict()
from_pairs = dict([("a", 1), ("b", 2)])
by_kwargs = dict(name="ნინო", age=20)

print(len(student))          # 3
print("name" in student)     # True — it searches the keys

dict

წვდომა — [] თუ get()?Access — [] or get()?

student = {"name": "ნინო", "score": 92}

print(student["name"])          # ნინო
print(student["email"])
# KeyError: 'email'

print(student.get("email"))            # None — no error
print(student.get("email", "არ არის")) # a default value
როდის რომელი [] — როცა გასაღები აუცილებლად უნდა არსებობდეს (მისი არარსებობა შეცდომაა) get() — როცა შესაძლოა არ იყოს და ნაგულისხმევი მნიშვნელობა გვაწყობს Which one when [] — when the key must be there (its absence is a bug) get() — when it may be missing and a default is fine
# adding and changing
student["email"] = "nino@example.com"    # a new key
student["score"] = 95                    # changing an existing one

# removing
del student["email"]
value = student.pop("score")             # remove and return
student.clear()

dict

გავლა ლექსიკონზეIterating a dictionary

scores = {"ნინო": 92, "გიორგი": 78, "ანა": 85}

print(scores.keys())     # dict_keys(['ნინო', 'გიორგი', 'ანა'])
print(scores.values())   # dict_values([92, 78, 85])
print(scores.items())    # dict_items([('ნინო', 92), ...])

# keys only (the default)
for name in scores:
    print(name, scores[name])

# values only
for score in scores.values():
    print(score)

# ✓ both at once — the most common form
for name, score in scores.items():
    print(f"{name:<10}{score:>5}")

print(sum(scores.values()) / len(scores))     # the average
print(max(scores, key=scores.get))            # the top student
.items()ესაა ლექსიკონზე გავლის სტანდარტული ხერხი — თითოეულ ბიჯზე tuple-ს აბრუნებს, რომელიც პირდაპირ ორ ცვლადად იშლება. .items()The standard way to loop a dictionary — each step yields a tuple that unpacks straight into two variables.

შაბლონიPattern

სიხშირის დათვლა — ლექსიკონის კლასიკაCounting frequencies — the classic use

text = "პროგრამირება პითონზე"
freq = {}

for ch in text:
    if ch == " ":
        continue
    if ch in freq:
        freq[ch] += 1
    else:
        freq[ch] = 1

# the same, more compactly:
for ch in text.replace(" ", ""):
    freq[ch] = freq.get(ch, 0) + 1

# sorted by frequency
for ch, n in sorted(freq.items(), key=lambda p: p[1], reverse=True):
    print(f"{ch}: {'█' * n} {n}")
მზა ინსტრუმენტი A ready-made tool
from collections import Counter

freq = Counter(text.replace(" ", ""))
print(freq.most_common(3))    # the 3 most frequent
ეს ამოცანა თითქმის ყოველთვის ხვდება დასკვნით გამოცდაზე. სთხოვე ჯერ ხელით დაწერონ, მერე Counter-ით. This exercise appears in nearly every final exam. Have them write it by hand first, then with Counter.

კომბინაციაCombining

ჩადგმული სტრუქტურებიNested structures

students = {
    "ნინო": {"age": 20, "scores": [92, 88, 95]},
    "გიორგი": {"age": 21, "scores": [78, 82, 70]},
}

print(students["ნინო"]["age"])          # 20
print(students["ნინო"]["scores"][0])    # 92

for name, info in students.items():
    scores = info["scores"]
    avg = sum(scores) / len(scores)
    print(f"{name:<10}{info['age']:>4}{avg:>8.1f}")

# a list of dictionaries — the most common shape of real data
group = [
    {"name": "ნინო", "score": 92},
    {"name": "გიორგი", "score": 78},
]

for s in group:
    print(s["name"], s["score"])

best = max(group, key=lambda s: s["score"])
print("საუკეთესო:", best["name"])
ეს სტრუქტურა შემთხვევითი არაა„სია ლექსიკონებისგან“ ზუსტად ისეა აგებული, როგორც JSON — ფორმატი, რომლითაც ვებ-სერვისები მონაცემს ცვლიან. This shape is no accidentA “list of dictionaries” is built exactly like JSON — the format web services exchange data in.

შედარებაComparison

ოთხი კრებული ერთ ცხრილშიFour collections in one table

ტიპიType ჩანაწერიWritten დალაგებულიOrdered ცვალებადიMutable დუბლიკატიDuplicates წვდომაAccess
list[1, 2, 3] ინდექსითBy index
tuple(1, 2, 3) ინდექსითBy index
set{1, 2, 3} მხოლოდ inin only
dict{"a": 1} (ჩაწერის რიგით)(insertion order) გასაღები ✘Keys ✘ გასაღებითBy key
როგორ ავირჩიოთ რიგი და ცვლილებაlist უცვლელი ჩანაწერი (კოორდინატი, RGB) → tuple უნიკალურობა ან სწრაფი inset სახელით მოძებნაdict How to choose Order and mutationlist A fixed record (a coordinate, an RGB triple) → tuple Uniqueness or a fast inset Lookup by namedict

შეფასებაAssessment

პრაქტიკული დავალება #3Practical assignment #3

8 ქულა · სრულდება აუდიტორიაში, დამოუკიდებლად 8 points · done in class, independently

  1. უნიკალური სიტყვებიტექსტიდან გამოყავი უნიკალური სიტყვები set-ით, დაბეჭდე ანბანურად დახარისხებული
  2. ორი ჯგუფის შედარებაორი სიმრავლიდან: საერთო სტუდენტები, მხოლოდ პირველში, მხოლოდ მეორეში მყოფნი
  3. სიტყვების სიხშირელექსიკონით დათვალე ტექსტში თითოეული სიტყვა; დაბეჭდე 5 ყველაზე ხშირი
  4. სატელეფონო წიგნაკიმენიუთი: დამატება, ძებნა (get-ით), წაშლა, სრული სია. მონაცემები ფაილში შეინახე
  5. უწყისისია ლექსიკონებისგან: სახელი + 3 ქულა. დაბეჭდე საშუალოთი დახარისხებული ცხრილი
  1. Unique wordsExtract the unique words from a text using a set and print them sorted alphabetically
  2. Comparing two groupsFrom two sets: the students in both, only in the first, only in the second
  3. Word frequencyCount every word in a text with a dictionary; print the 5 most frequent
  4. A phone bookWith a menu: add, look up (using get), delete, list all. Persist the data to a file
  5. A grade tableA list of dictionaries: a name plus 3 scores. Print a table sorted by average
რჩევადავალება 4 და 5 IX კვირის ფაილებთან მუშაობასაც იყენებს — ესაა კარგი ინტეგრაცია. NoteTasks 4 and 5 also draw on week IX’s file handling — a good integration point.

შემაჯამებელიWrap-up

რა უნდა დაგამახსოვრდესWhat to remember

შემდეგი — ლექცია 12შეცდომები და მათი დამუშავება: try / except / else / finally, with ... as. Next — lecture 12Errors and how to handle them: try / except / else / finally, with ... as.