ლექცია 10 · X კვირაLecture 10 · Week X

სიები და
Tuple
Lists and
tuples

შექმნა, წაშლა, დამატება/ამოშლა, დახარისხება · მრავალგანზომილებიანი სიები · tuple მონაცემთა ტიპი Creating, adding, removing, sorting · multidimensional lists · the tuple type

მოტივაციაMotivation

რატომ არ გვყოფნის ცალკეული ცვლადებიWhy separate variables are not enough

სიის გარეშეWithout a list

score1 = 92
score2 = 78
score3 = 85
# …and what if there are 200 students?

total = score1 + score2 + score3

სიითWith a list

scores = [92, 78, 85, 61, 100]

print(sum(scores))
print(max(scores))
print(len(scores))

for s in scores:
    print(s)
სია (list)დალაგებული, ცვალებადი კრებული, რომელიც ნებისმიერი ტიპის ელემენტს იტევს — ერთდროულადაც კი. A listAn ordered, mutable collection that can hold any type of element — even mixed together.

საფუძველიFundamentals

შექმნა და წვდომაCreating and accessing

numbers = [10, 20, 30, 40, 50]
names = ["ნინო", "გიორგი", "ანა"]
mixed = [1, "ტექსტი", 3.14, True, None]
empty = []
also_empty = list()

from_string = list("Python")   # ['P','y','t','h','o','n']
from_range = list(range(5))    # [0, 1, 2, 3, 4]

print(numbers[0])      # 10
print(numbers[-1])     # 50
print(numbers[1:4])    # [20, 30, 40]
print(numbers[::-1])   # [50, 40, 30, 20, 10]
print(len(numbers))    # 5
ინდექსაცია იგივეა, რაც სტრიქონებში0-დან იწყება, -1 ბოლოა, ამონაჭერში stop არ შედის. ერთხელ ნასწავლი წესი ორივეზე ვრცელდება. Indexing works exactly as with stringsIt starts at 0, -1 is the last, and stop is excluded from a slice. Learn the rule once, use it for both.

მთავარი განსხვავებაThe key difference

სია ცვალებადია (mutable)Lists are mutable

s = "Python"
s[0] = "J"
# TypeError!
lst = [1, 2, 3]
lst[0] = 100
print(lst)      # [100, 2, 3]

lst[1:3] = [9, 9, 9]
print(lst)      # [100, 9, 9, 9]
შედეგი, რომელიც უნდა გესმოდეს A consequence you must understand
a = [1, 2, 3]
b = a               # the same list, not a copy!
b.append(4)
print(a)            # [1, 2, 3, 4] — a changed too

c = a.copy()        # a real copy
c = a[:]            # the same, via a slice
c = list(a)         # the same again
c.append(5)
print(a)            # [1, 2, 3, 4] — unchanged
ეს ერთ-ერთი ყველაზე მნიშვნელოვანი ცნებაა კურსში. დაფაზე დახატე: ორი სახელი ერთ ყუთზე მიმართული ისრებით. One of the most important ideas in the course. Draw it: two names with arrows pointing at one box.

მეთოდებიMethods

ელემენტების დამატებაAdding elements

lst = [1, 2, 3]

lst.append(4)            # one element, at the end
print(lst)               # [1, 2, 3, 4]

lst.insert(0, 0)         # at a given position
print(lst)               # [0, 1, 2, 3, 4]

lst.extend([5, 6])       # several elements
print(lst)               # [0, 1, 2, 3, 4, 5, 6]

lst = lst + [7, 8]       # a new list (slow for big data)
lst += [9]               # equivalent to extend
append vs extend append vs extend
a = [1, 2]
a.append([3, 4])    # [1, 2, [3, 4]]  — a nested list!
b = [1, 2]
b.extend([3, 4])    # [1, 2, 3, 4]    — the elements

მეთოდებიMethods

ელემენტების წაშლაRemoving elements

lst = [10, 20, 30, 20, 40]

lst.remove(20)        # the first match, by value
print(lst)            # [10, 30, 20, 40]

x = lst.pop()         # the last one, and returns it
print(x, lst)         # 40 [10, 30, 20]

y = lst.pop(0)        # by index
print(y, lst)         # 10 [30, 20]

del lst[0]            # by index, returns nothing
print(lst)            # [20]

lst.clear()           # everything
print(lst)            # []
ფრთხილადremove() ვერ პოვნისას ValueError-ს ისვრის. ჯერ შეამოწმე: if x in lst:.
არასდროს შეცვალო სია ციკლში, რომელიც სწორედ მასზე გადის — ელემენტები „გამოგრჩება“.
Carefulremove() raises ValueError if the value is absent. Check first: if x in lst:.
Never modify a list while looping over that same list — elements get skipped.

ძებნაSearching

ძებნა და დათვლაSearching and counting

scores = [92, 78, 85, 78, 61]

print(78 in scores)          # True
print(100 not in scores)     # True

print(scores.index(78))      # 1 — the first match
print(scores.count(78))      # 2 — how many times it occurs

print(len(scores))           # 5
print(sum(scores))           # 394
print(min(scores), max(scores))   # 61 92
print(sum(scores) / len(scores))  # 78.8
index()ვერ პოვნისას — ValueError. ჯერ in-ით შეამოწმე. index()raises ValueError when not found. Check with in first.
sum, min, maxჩაშენებული ფუნქციებია (V კვირა) — სიაზეც უშუალოდ მუშაობს. sum, min, maxare built-ins (week V) — they work directly on a list.

დახარისხებაSorting

sort() თუor sorted()?

lst = [3, 1, 2]
lst.sort()
print(lst)        # [1, 2, 3]
print(lst.sort()) # None!
lst = [3, 1, 2]
new = sorted(lst)
print(new)        # [1, 2, 3]
print(lst)        # [3, 1, 2] unchanged
nums = [5, 2, 9, 1]
nums.sort(reverse=True)          # [9, 5, 2, 1]

names = ["გიორგი", "ანა", "ნინო"]
names.sort()                     # alphabetically

words = ["python", "java", "c"]
words.sort(key=len)              # by length

students = [("ნინო", 92), ("გიორგი", 78), ("ანა", 85)]
students.sort(key=lambda s: s[1], reverse=True)
print(students)   # [('ნინო',92), ('ანა',85), ('გიორგი',78)]

nums.reverse()                   # simply reverse the order
ტიპური შეცდომაlst = lst.sort()lst გახდება None. sort() არაფერს აბრუნებს! A typical mistakelst = lst.sort() makes lst become None. sort() returns nothing!

Python-ური სტილიPythonic style

List comprehension

ჩვეულებრივი ციკლიAn ordinary loop

squares = []
for n in range(1, 6):
    squares.append(n ** 2)
print(squares)     # [1, 4, 9, 16, 25]

ერთ ხაზშიOn one line

squares = [n ** 2 for n in range(1, 6)]
print(squares)     # [1, 4, 9, 16, 25]
# with a condition
evens = [n for n in range(20) if n % 2 == 0]

# transforming
names = ["ნინო", "გიორგი"]
lengths = [len(n) for n in names]        # [4, 6]

# filtering + transforming
scores = [92, 45, 78, 30, 85]
passed = [s for s in scores if s >= 51]  # [92, 78, 85]

# numbers out of text
line = "10 20 30"
nums = [int(x) for x in line.split()]    # [10, 20, 30]
წაიკითხე ასე„[რა for თითოეული in საიდან if პირობა]“. თუ ერთ ხაზში აღარ ეტევა — დაწერე ჩვეულებრივი ციკლი. Read it as“[what for each item in where from if condition]”. If it no longer fits on one line, write an ordinary loop.

სტრუქტურაStructure

მრავალგანზომილებიანი სიებიMultidimensional lists

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

print(matrix[0])        # [1, 2, 3]
print(matrix[1][2])     # 6   — row 2, column 3
print(len(matrix))      # 3   rows
print(len(matrix[0]))   # 3   columns

# printing it
for row in matrix:
    for value in row:
        print(f"{value:4}", end="")
    print()

# the total
total = sum(sum(row) for row in matrix)   # 45

# building one in a loop
grid = [[0] * 3 for _ in range(3)]        # ✓ correct
# grid = [[0] * 3] * 3                    # ✗ all three rows are the same!
კლასიკური ხაფანგი[[0] * 3] * 3 ქმნის სამ მიმართვას ერთსა და იმავე სიაზე. grid[0][0] = 5 სამივე რიგს შეცვლის. A classic trap[[0] * 3] * 3 creates three references to the same list. grid[0][0] = 5 changes all three rows.

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

tuple — უცვლელი სიაtuple — an immutable list

point = (10, 20)
colors = ("წითელი", "მწვანე", "ლურჯი")
single = (42,)          # the comma is mandatory!
without = 1, 2, 3       # the parentheses are optional

print(point[0])         # 10
print(len(colors))      # 3
print("წითელი" in colors)   # True

point[0] = 99
# TypeError: 'tuple' object does not support item assignment

უსაფრთხოებაSafety

შემთხვევით ვერ შეცვლი — კონსტანტებისთვის იდეალურია

You cannot change it by accident — ideal for constants

სისწრაფეSpeed

სიაზე ოდნავ სწრაფი და ნაკლებ მეხსიერებას იკავებს

Slightly faster than a list and uses less memory

გასაღებიAs a key

ლექსიკონის გასაღები შეიძლება იყოს, სია — ვერა (XI კვირა)

It can be a dictionary key; a list cannot (week XI)

tuple

დაშლა (unpacking) და zipUnpacking and zip

point = (10, 20)
x, y = point
print(x, y)                  # 10 20

a, b = b, a                  # swapping — also a tuple

def min_max(data):
    return min(data), max(data)

low, high = min_max([4, 9, 1])

# enumerate — index + value
names = ["ნინო", "გიორგი", "ანა"]
for i, name in enumerate(names, start=1):
    print(f"{i}. {name}")

# zip — two lists in parallel
scores = [92, 78, 85]
for name, score in zip(names, scores):
    print(f"{name:<10}{score:>5}")

pairs = list(zip(names, scores))
# [('ნინო', 92), ('გიორგი', 78), ('ანა', 85)]
enumerate და zipესაა ორი ფუნქცია, რომელიც კოდს ყველაზე მეტად აპითონურებს. range(len(...))-ს თითქმის ყოველთვის ცვლის. enumerate and zipThe two functions that make code most Pythonic. They replace range(len(...)) almost every time.

სრული მაგალითიFull example

სტუდენტების უწყისიA student ranking

students = []          # a list of tuples


def add(name, score):
    students.append((name, score))


def report():
    if not students:
        print("სია ცარიელია")
        return

    ranked = sorted(students, key=lambda s: s[1], reverse=True)
    scores = [s[1] for s in ranked]

    print(f"\n{'#':<4}{'სახელი':<15}{'ქულა':>6}")
    print("-" * 25)
    for i, (name, score) in enumerate(ranked, start=1):
        print(f"{i:<4}{name:<15}{score:>6}")

    print("-" * 25)
    print(f"საშუალო: {sum(scores) / len(scores):.2f}")
    print(f"უმაღლესი: {max(scores)} · უმდაბლესი: {min(scores)}")
    print(f"ჩააბარა: {len([s for s in scores if s >= 51])}")


add("ნინო", 92)
add("გიორგი", 78)
add("ანა", 85)
add("ლევანი", 45)
report()

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

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

სახლში1) სიიდან დუბლიკატების მოშორება (set-ის გარეშე). 2) ორი სიის შერწყმა და დახარისხება. 3) მატრიცის ტრანსპონირება. 4) ფაილიდან რიცხვების წაკითხვა სიაში და სტატისტიკის გამოტანა. At home1) Remove duplicates from a list (without set). 2) Merge two lists and sort the result. 3) Transpose a matrix. 4) Read numbers from a file into a list and report statistics.
შემდეგი — ლექცია 11სიმრავლე (set) და ლექსიკონი (dict) + პრაქტიკული დავალება #3. Next — lecture 11Sets (set) and dictionaries (dict) + practical assignment #3.