IlmHamroh
Python kursi/Satrlar chuqur5/12-dars24 daqiqa
Mundarija (23)

4.5-dars: Metodlar — bo'lish va birlashtirish

4-QISM — SATRLAR CHUQUR · 5-dars


1. Kirish va motivatsiya

Matnni bo'laklarga ajratish va qayta birlashtirish — matn bilan ishlashning asosi:

python
"Ali,25,Toshkent".split(",")            # CSV qatori
"salom dunyo".split()                   # so'zlar
matn.splitlines()                       # qatorlar
"/home/user/fayl.txt".rsplit("/", 1)    # yo'l va fayl nomi
"kalit=qiymat".partition("=")           # bir marta bo'lish
", ".join(royxat)                       # birlashtirish

Bu metodlarda ko'p nozik jihat bor va ular jimgina noto'g'ri natija beradi:

python
print("  a   b  ".split())              # ['a', 'b']
print("  a   b  ".split(" "))           # ['', '', 'a', '', '', 'b', '', '']

print("a,b,,c".split(","))              # ['a', 'b', '', 'c'] — bo'sh element
print("".split(","))                    # [''] — bo'sh satr emas, bir elementli!
print("".split())                       # [] — bo'sh ro'yxat

print(", ".join([1, 2]))                # ❌ TypeError

Bu darsda hammasini tartibga solamiz.


2. Nazariya — chuqur tushuntirish

2.1. split() — ikki xil xatti-harakat

Bu — eng muhim farq va eng ko'p xato manbai.

Argumentsiz — "bo'shliq rejimi":

python
matn = "  Ali   Valiyev  \t Toshkent \n"

print(matn.split())         # ['Ali', 'Valiyev', 'Toshkent']

Xatti-harakati:

  • Har qanday bo'shliq belgisi bo'yicha bo'ladi ( , \t, \n, \r, )
  • Ketma-ket bo'shliqlarni bitta ajratgich deb qabul qiladi
  • Boshi va oxiridagi bo'shliqni e'tiborsiz qoldiradi
  • Bo'sh element qaytarmaydi

Argument bilan — "aniq ajratgich rejimi":

python
print(matn.split(" "))
# ['', '', 'Ali', '', '', 'Valiyev', '', '\t', 'Toshkent', '\n']

Xatti-harakati:

  • Faqat ko'rsatilgan satr bo'yicha bo'ladi
  • Har bir uchrashuv — alohida ajratgich
  • Bo'sh elementlar qaytadi
  • Boshi va oxiridagi ajratgich ham hisobga olinadi

Jadval:

Kirish .split() .split(" ")
"a b" ['a', 'b'] ['a', 'b']
"a b" ['a', 'b'] ['a', '', 'b']
" a b " ['a', 'b'] ['', 'a', 'b', '']
"a\tb" ['a', 'b'] ['a\tb']
"" [] ['']
" " [] ['', '', '', '']

Qachon qaysi biri?

python
# Erkin matnni so'zlarga → argumentsiz
sozlar = matn.split()

# Aniq formatdagi ma'lumot (CSV) → argument bilan
qismlar = qator.split(",")

Bo'sh satr tuzog'i:

python
print("".split())           # []      — bo'sh ro'yxat
print("".split(","))        # ['']    — BIR elementli ro'yxat!
print(len("".split(",")))   # 1

Bu — CSV o'qishda muammo keltiradi:

python
qator = ""
qismlar = qator.split(",")
ism = qismlar[0]            # '' — xato yo'q, lekin bo'sh
yosh = qismlar[1]           # ❌ IndexError

Yechim:

python
if not qator.strip():
    continue                # bo'sh qatorni o'tkazib yuborish

2.2. maxsplit — bo'lishlar soni

python
matn = "a:b:c:d"

print(matn.split(":"))          # ['a', 'b', 'c', 'd']
print(matn.split(":", 1))       # ['a', 'b:c:d']
print(matn.split(":", 2))       # ['a', 'b', 'c:d']
print(matn.split(":", 0))       # ['a:b:c:d']
print(matn.split(":", -1))      # ['a', 'b', 'c', 'd'] — cheksiz (sukut)

Amaliy foydalanish:

python
# HTTP sarlavhasi — qiymatda ikki nuqta bo'lishi mumkin
sarlavha = "Content-Type: text/html; charset=utf-8"
nom, qiymat = sarlavha.split(":", 1)
print(nom.strip())              # 'Content-Type'
print(qiymat.strip())           # 'text/html; charset=utf-8'

maxsplit kafolat beradi: natija aniq maxsplit + 1 ta element bo'ladi (agar ajratgich yetarli bo'lsa).

python
# ❌ Xavfli — nechta element kelishini bilmaysiz
nom, qiymat = sarlavha.split(":")       # ValueError: too many values

# ✅ Xavfsiz
nom, qiymat = sarlavha.split(":", 1)

2.3. rsplit — oxiridan bo'lish

python
yol = "/home/user/hujjatlar/hisobot.pdf"

print(yol.split("/", 1))        # ['', 'home/user/hujjatlar/hisobot.pdf']
print(yol.rsplit("/", 1))       # ['/home/user/hujjatlar', 'hisobot.pdf']

Amaliy misollar:

python
# Fayl nomi va kengaytma
fayl = "hisobot.2026.pdf"
print(fayl.rsplit(".", 1))              # ['hisobot.2026', 'pdf']
print(fayl.split(".", 1))               # ['hisobot', '2026.pdf'] — noto'g'ri

# Oxirgi so'z
matn = "Bu bir necha so'zdan iborat gap"
print(matn.rsplit(maxsplit=1))          # ['Bu bir necha so'zdan iborat', 'gap']

# Domen
email = "ali.valiyev@company.co.uk"
print(email.rsplit("@", 1))             # ['ali.valiyev', 'company.co.uk']

Qoida:

  • Boshidan aniq son bo'lak kerak → split(x, n)
  • Oxiridan aniq son bo'lak kerak → rsplit(x, n)

2.4. partition va rpartition

Bu metodlar doim uchta element qaytaradi:

python
matn = "kalit=qiymat"

print(matn.partition("="))          # ('kalit', '=', 'qiymat')
print(matn.rpartition("="))         # ('kalit', '=', 'qiymat')

# Topilmasa
print(matn.partition("|"))          # ('kalit=qiymat', '', '')
print(matn.rpartition("|"))         # ('', '', 'kalit=qiymat')

Farqi:

Metod Topilmasa natija
partition (butun_satr, '', '')
rpartition ('', '', butun_satr)

split(x, 1) bilan solishtiring:

python
matn = "kalit=qiymat"
print(matn.split("=", 1))           # ['kalit', 'qiymat']     — 2 element
print(matn.partition("="))          # ('kalit', '=', 'qiymat') — 3 element

matn = "kalitsiz"
print(matn.split("=", 1))           # ['kalitsiz']            — 1 element!
print(matn.partition("="))          # ('kalitsiz', '', '')    — 3 element

partition afzalligi: natija uzunligi kafolatlangan.

python
# ❌ split — element soni o'zgaruvchan
qismlar = qator.split("=", 1)
if len(qismlar) == 2:
    kalit, qiymat = qismlar
else:
    kalit, qiymat = qismlar[0], ""

# ✅ partition — doim 3 ta
kalit, ajratgich, qiymat = qator.partition("=")
if not ajratgich:
    print("Ajratgich topilmadi")

Amaliy misol — sozlama fayli:

python
SOZLAMA = """
host = localhost
port = 8000
debug = true
# bu izoh
noto'g'ri qator
"""

for qator in SOZLAMA.splitlines():
    qator = qator.strip()
    if not qator or qator.startswith("#"):
        continue

    kalit, ajratgich, qiymat = qator.partition("=")
    if not ajratgich:
        print(f"  ⚠️ Noto'g'ri qator: {qator!r}")
        continue

    print(f"  {kalit.strip():<8} = {qiymat.strip()!r}")
text
  host     = 'localhost'
  port     = '8000'
  debug    = 'true'
  ⚠️ Noto'g'ri qator: "noto'g'ri qator"

rpartition qachon?

python
# Fayl kengaytmasi — oxirgi nuqta
fayl = "arxiv.tar.gz"
nom, _, kengaytma = fayl.rpartition(".")
print(nom, kengaytma)               # 'arxiv.tar' 'gz'

# Email domeni — oxirgi @
email = "a@b@company.com"           # texnik jihatdan mumkin
_, _, domen = email.rpartition("@")
print(domen)                        # 'company.com'

2.5. splitlines — qatorlarga bo'lish

python
matn = "Birinchi\nIkkinchi\nUchinchi"

print(matn.splitlines())            # ['Birinchi', 'Ikkinchi', 'Uchinchi']
print(matn.split("\n"))             # bir xil — bu holda

Farq — chegara holatlarida:

python
matn = "a\nb\n"

print(matn.splitlines())            # ['a', 'b']       — oxirgi bo'sh element YO'Q
print(matn.split("\n"))             # ['a', 'b', '']   — bor

print("".splitlines())              # []
print("".split("\n"))               # ['']

splitlines barcha qator ajratgichini biladi:

python
matn = "a\nb\rc\r\nd\vE\fF\x1cG\x85H
I
J"
print(matn.splitlines())
# ['a', 'b', 'c', 'd', 'E', 'F', 'G', 'H', 'I', 'J']

print(matn.split("\n"))
# ['a', 'b\rc\r', 'd\vE\fF\x1cG\x85H
I
J']
Belgi Nomi
\n Yangi qator (Unix)
\r Karetka (eski Mac)
\r\n Windows
\v \f Vertikal tab, sahifa oxiri
\x1c \x1d \x1e Fayl/guruh/yozuv ajratgichi
\x85 Keyingi qator (NEL)

| 
 
 | Qator/xatboshi ajratgichi |

Amaliy natija: fayl Windows'da yozilgan bo'lsa (\r\n), split("\n") har qator oxirida \r qoldiradi:

python
matn = "a\r\nb\r\n"
print(matn.split("\n"))             # ['a\r', 'b\r', '']  ← \r qoldi!
print(matn.splitlines())            # ['a', 'b']          ✅

Qoida: qatorlarga bo'lish uchun doim splitlines().

keepends — ajratgichni saqlash:

python
matn = "a\nb\n"
print(matn.splitlines(keepends=True))       # ['a\n', 'b\n']

Fayl qayta yozishda foydali.

2.6. join — birlashtirish

python
qismlar = ["olma", "anor", "uzum"]

print(", ".join(qismlar))           # 'olma, anor, uzum'
print("".join(qismlar))             # 'olmaanoruzum'
print("\n".join(qismlar))           # har biri yangi qatorda
print(" | ".join(qismlar))          # 'olma | anor | uzum'

join ajratgichda chaqiriladi, ro'yxatda emas:

python
qismlar.join(", ")                  # ❌ AttributeError
", ".join(qismlar)                  # ✅

Bu — boshida g'alati tuyuladi. Sabab: join har qanday iteratsiya qilinadigan obyekt bilan ishlaydi, faqat ro'yxat bilan emas:

python
print(", ".join("abc"))                     # 'a, b, c' — satr
print(", ".join(("a", "b")))                # 'a, b'    — juftlik
print(", ".join({"a", "b"}))                # to'plam (tartib noaniq)
print(", ".join({"a": 1, "b": 2}))          # 'a, b'    — lug'at kalitlari
print(", ".join(str(x) for x in range(3)))  # '0, 1, 2' — generator

Agar join ro'yxat metodi bo'lganida, uni har bir turga alohida qo'shish kerak bo'lardi.

Faqat satrlar bilan ishlaydi:

python
sonlar = [1, 2, 3]

print(", ".join(sonlar))                    # ❌ TypeError
print(", ".join(str(x) for x in sonlar))    # ✅ '1, 2, 3'
print(", ".join(map(str, sonlar)))          # ✅ bir xil

Nega avtomatik aylantirmaydi? Chunki bu — yashirin xatti-harakat bo'lardi. Python "Aniq yashirinlikdan yaxshi" qoidasiga amal qiladi (1.5-dars).

Tezlik — join va +=:

python
import time

N = 100_000

boshlandi = time.perf_counter()
natija = ""
for i in range(N):
    natija += str(i)
vaqt_qoshish = time.perf_counter() - boshlandi

boshlandi = time.perf_counter()
natija = "".join(str(i) for i in range(N))
vaqt_join = time.perf_counter() - boshlandi

print(f"  += bilan:   {vaqt_qoshish * 1000:>8.1f} ms")
print(f"  join bilan: {vaqt_join * 1000:>8.1f} ms")

Satrlar o'zgarmas (3.7-dars), shuning uchun += har safar yangi satr yaratadi. join esa kerakli hajmni bir marta hisoblab, bir marta ajratadi.

Diqqat: CPython += ni ba'zi holatlarda optimallashtiradi, shuning uchun farq kutilganidan kichik bo'lishi mumkin. Lekin bu kafolatlanmagan — join doim to'g'ri tanlov.

2.7. split va join birgalikda

Universal tozalash idiomasi (4.4-dars):

python
print(" ".join("  a   b  ".split()))        # 'a b'

Ajratgichni almashtirish:

python
csv = "a,b,c"
print(" | ".join(csv.split(",")))           # 'a | b | c'
print(csv.replace(",", " | "))              # bir xil, lekin tezroq

replace bu holda yaxshiroq — bir amal.

Lekin bo'shliqlarni normallashtirish kerak bo'lsa split/join kerak:

python
csv = "a , b ,  c"
print(" | ".join(q.strip() for q in csv.split(",")))    # 'a | b | c'

Qatorlarga chekinish qo'shish:

python
matn = "birinchi\nikkinchi\nuchinchi"
print("\n".join("    " + q for q in matn.splitlines()))

Yoki textwrap bilan (11-darsda):

python
import textwrap
print(textwrap.indent(matn, "    "))

So'zlarni teskari qilish:

python
matn = "Salom dunyo va olam"
print(" ".join(reversed(matn.split())))     # 'olam va dunyo Salom'
print(" ".join(matn.split()[::-1]))         # bir xil

2.8. Ko'p qatorli va ichma-ich bo'lish

CSV — oddiy holat:

python
CSV = """ism,yosh,shahar
Ali,25,Toshkent
Vali,30,Samarqand"""

qatorlar = CSV.splitlines()
sarlavha = qatorlar[0].split(",")
print(sarlavha)                     # ['ism', 'yosh', 'shahar']

for qator in qatorlar[1:]:
    qiymatlar = qator.split(",")
    print(dict(zip(sarlavha, qiymatlar)))
text
{'ism': 'Ali', 'yosh': '25', 'shahar': 'Toshkent'}
{'ism': 'Vali', 'yosh': '30', 'shahar': 'Samarqand'}

Lekin haqiqiy CSV murakkabroq:

python
qator = 'Ali,"Toshkent, Chilonzor",25'
print(qator.split(","))
# ['Ali', '"Toshkent', ' Chilonzor"', '25']  ❌ noto'g'ri!

Tirnoq ichidagi vergul ajratgich emas. Haqiqiy CSV uchun csv modulini ishlating:

python
import csv
import io

qator = 'Ali,"Toshkent, Chilonzor",25'
print(next(csv.reader(io.StringIO(qator))))
# ['Ali', 'Toshkent, Chilonzor', '25']  ✅

16-qismda batafsil.

Ichma-ich bo'lish:

python
MALUMOT = "ali:25;vali:30;guli:28"

for yozuv in MALUMOT.split(";"):
    ism, yosh = yozuv.split(":")
    print(f"  {ism:<8} {yosh}")

Xavfsizroq — partition bilan:

python
for yozuv in MALUMOT.split(";"):
    ism, ajratgich, yosh = yozuv.partition(":")
    if not ajratgich:
        print(f"  ⚠️ Noto'g'ri yozuv: {yozuv!r}")
        continue
    print(f"  {ism:<8} {yosh}")

2.9. Boshqa foydali usullar

str.splitlines() va fayl o'qish:

python
# Faylni qatorlarga o'qish
with open("fayl.txt", encoding="utf-8") as f:
    qatorlar = f.read().splitlines()        # \n siz
    # yoki
    qatorlar = f.readlines()                # \n bilan
    # yoki (eng samarali — katta fayl uchun)
    for qator in f:
        qator = qator.rstrip("\n")

16-qismda batafsil.

zip bilan juftlash:

python
kalitlar = "ism,yosh,shahar".split(",")
qiymatlar = "Ali,25,Toshkent".split(",")

print(dict(zip(kalitlar, qiymatlar)))

itertools bilan guruhlash (15-qism):

python
from itertools import batched     # Python 3.12+

sozlar = "a b c d e f g".split()
print(list(batched(sozlar, 3)))
# [('a', 'b', 'c'), ('d', 'e', 'f'), ('g',)]

3.12 gacha — kesim bilan (4.2-dars):

python
def boklarga_bol(x, n):
    return [x[i:i + n] for i in range(0, len(x), n)]

Bo'sh elementlarni filtrlash:

python
matn = "a,,b,,,c"
print(matn.split(","))                          # ['a', '', 'b', '', '', 'c']
print([q for q in matn.split(",") if q])        # ['a', 'b', 'c']
print(list(filter(None, matn.split(","))))      # bir xil

filter(None, ...) — falsy elementlarni olib tashlaydi (3.5-dars).


3. Tez ma'lumotnoma

Bo'lish

python
matn.split()                bo'shliq rejimi — bo'sh element YO'Q
matn.split(x)               aniq ajratgich — bo'sh element BOR
matn.split(x, n)            ko'pi bilan n marta
matn.rsplit(x, n)           oxiridan
matn.splitlines()           ⭐ barcha qator ajratgichi
matn.splitlines(keepends=True)
matn.partition(x)           ⭐ DOIM 3 element
matn.rpartition(x)

Birlashtirish

python
ajratgich.join(iterable)    ⭐ ajratgichda chaqiriladi
", ".join(map(str, sonlar)) faqat satrlar!

Tuzoqlar

python
"  a  b  ".split()          → ['a', 'b']
"  a  b  ".split(" ")       → ['', '', 'a', '', 'b', '', '']
"".split()                  → []
"".split(",")               → ['']  ← BIR element!
"a\r\nb".split("\n")        → ['a\r', 'b']  ← \r qoldi
", ".join([1, 2])           → ❌ TypeError
royxat.join(", ")           → ❌ AttributeError

Idiomalar

python
" ".join(matn.split())              bo'shliqlarni normallashtirish
nom, _, qiymat = q.partition("=")   xavfsiz bo'lish
nom, kengaytma = f.rsplit(".", 1)   fayl kengaytmasi
"".join(str(x) for x in sonlar)     tez birlashtirish
[q for q in x.split(",") if q]      bo'shlarni filtrlash

4. Batafsil misollar

Misol 1 — split() va split(x) farqi

python
"""Ikki rejim — butunlay boshqa xatti-harakat."""

namunalar = [
    "a b",
    "a  b",
    " a b ",
    "  a   b  ",
    "a\tb",
    "a\nb",
    "",
    "   ",
    "a",
]

print(f"{'Kirish':<16} {'.split()':<20} {'.split(\" \")'}")
print("─" * 62)
for s in namunalar:
    print(f"{s!r:<16} {str(s.split()):<20} {s.split(' ')}")

print("\n=== Bo'sh satr — eng muhim farq ===")
print(f"  ''.split()      → {''.split()!r}   uzunlik: {len(''.split())}")
print(f"  ''.split(',')   → {''.split(',')!r}  uzunlik: {len(''.split(','))}")

print("\n=== Nima uchun bu muhim ===")
qatorlar = ["Ali,25", "", "Vali,30", "   "]
print("  ❌ Tekshiruvsiz:")
for q in qatorlar:
    qismlar = q.split(",")
    try:
        ism, yosh = qismlar
        print(f"    {ism:<8} {yosh}")
    except ValueError as x:
        print(f"    ⚠️ {q!r}: {x}")

print("\n  ✅ Tekshiruv bilan:")
for q in qatorlar:
    if not q.strip():
        continue
    qismlar = q.split(",")
    if len(qismlar) != 2:
        print(f"    ⚠️ Noto'g'ri format: {q!r}")
        continue
    ism, yosh = qismlar
    print(f"    {ism:<8} {yosh}")

print("\n=== maxsplit ===")
matn = "a:b:c:d"
for n in [None, 0, 1, 2, 10]:
    natija = matn.split(":") if n is None else matn.split(":", n)
    print(f"  split(':', {str(n):<4}) → {natija}")

print("\n=== rsplit ===")
yol = "/home/user/hujjatlar/hisobot.tar.gz"
print(f"  Yo'l: {yol}")
print(f"  split('/', 1)  → {yol.split('/', 1)}")
print(f"  rsplit('/', 1) → {yol.rsplit('/', 1)}")
print(f"  rsplit('.', 1) → {yol.rsplit('.', 1)}")
print(f"  split('.', 1)  → {yol.split('.', 1)}")
text
Kirish           .split()             .split(" ")
──────────────────────────────────────────────────────────────
'a b'            ['a', 'b']           ['a', 'b']
'a  b'           ['a', 'b']           ['a', '', 'b']
' a b '          ['a', 'b']           ['', 'a', 'b', '']
'  a   b  '      ['a', 'b']           ['', '', 'a', '', '', 'b', '', '']
'a\tb'           ['a', 'b']           ['a\tb']
'a\nb'           ['a', 'b']           ['a\nb']
''               []                   ['']
'   '            []                   ['', '', '', '']
'a'              ['a']                ['a']

=== Bo'sh satr — eng muhim farq ===
  ''.split()      → []   uzunlik: 0
  ''.split(',')   → ['']  uzunlik: 1

=== Nima uchun bu muhim ===
  ❌ Tekshiruvsiz:
    Ali      25
    ⚠️ '': not enough values to unpack (expected 2, got 1)
    Vali     30
    ⚠️ '   ': not enough values to unpack (expected 2, got 1)

  ✅ Tekshiruv bilan:
    Ali      25
    Vali     30

Nima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.

Misol 2 — partition va sozlama fayli

python
"""partition — natija uzunligi kafolatlangan."""

SOZLAMA = """
# Server sozlamalari
host = localhost
port = 8000
debug = true
url = https://example.com:443/yol

# Noto'g'ri qatorlar
bu ajratgichsiz qator
= qiymatsiz kalit
kalit =
"""


def sozlamani_oqi(matn: str) -> tuple[dict[str, str], list[str]]:
    """Sozlama faylini o'qiydi. (sozlamalar, xatolar) qaytaradi."""
    sozlamalar: dict[str, str] = {}
    xatolar: list[str] = []

    for raqam, qator in enumerate(matn.splitlines(), 1):
        qator = qator.strip()

        # Bo'sh va izoh qatorlari
        if not qator or qator.startswith("#"):
            continue

        # ⭐ partition — DOIM 3 element
        kalit, ajratgich, qiymat = qator.partition("=")

        if not ajratgich:
            xatolar.append(f"{raqam}-qator: ajratgich yo'q — {qator!r}")
            continue

        kalit = kalit.strip()
        qiymat = qiymat.strip()

        if not kalit:
            xatolar.append(f"{raqam}-qator: kalit bo'sh — {qator!r}")
            continue

        if not qiymat:
            xatolar.append(f"{raqam}-qator: qiymat bo'sh — {qator!r}")
            continue

        sozlamalar[kalit] = qiymat

    return sozlamalar, xatolar


sozlamalar, xatolar = sozlamani_oqi(SOZLAMA)

print("┌─ SOZLAMALAR")
for k, v in sozlamalar.items():
    print(f"│  {k:<8} = {v!r}")
print("│")
print("│  Xatolar:")
for x in xatolar:
    print(f"│    ⚠️ {x}")
print("└─")

print("\n=== partition vs split solishtiruvi ===")
sinovlar = ["kalit=qiymat", "kalitsiz", "=qiymatsiz", "a=b=c", ""]

print(f"{'Kirish':<16} {'partition(\"=\")':<32} {'split(\"=\", 1)'}")
print("─" * 74)
for s in sinovlar:
    p = s.partition("=")
    sp = s.split("=", 1)
    print(f"{s!r:<16} {str(p):<32} {sp}")

print("\n  partition: DOIM 3 element → xavfsiz ochish")
print("  split:     1 yoki 2 element → tekshirish kerak")

print("\n=== rpartition — oxirgi ajratgich ===")
namunalar = [
    ("arxiv.tar.gz", "."),
    ("a@b@company.com", "@"),
    ("/home/user/fayl.txt", "/"),
]
for matn, ajr in namunalar:
    p = matn.partition(ajr)
    rp = matn.rpartition(ajr)
    print(f"  {matn!r:<24} {ajr!r}")
    print(f"    partition  → {p}")
    print(f"    rpartition → {rp}")
text
┌─ SOZLAMALAR
│  host     = 'localhost'
│  port     = '8000'
│  debug    = 'true'
│  url      = 'https://example.com:443/yol'
│
│  Xatolar:
│    ⚠️ 10-qator: ajratgich yo'q — 'bu ajratgichsiz qator'
│    ⚠️ 11-qator: kalit bo'sh — '= qiymatsiz kalit'
│    ⚠️ 12-qator: qiymat bo'sh — 'kalit ='
└─

=== partition vs split solishtiruvi ===
Kirish           partition("=")                   split("=", 1)
──────────────────────────────────────────────────────────────────────────
'kalit=qiymat'   ('kalit', '=', 'qiymat')         ['kalit', 'qiymat']
'kalitsiz'       ('kalitsiz', '', '')             ['kalitsiz']
'=qiymatsiz'     ('', '=', 'qiymatsiz')           ['', 'qiymatsiz']
'a=b=c'          ('a', '=', 'b=c')                ['a', 'b=c']
''               ('', '', '')                     ['']

  partition: DOIM 3 element → xavfsiz ochish
  split:     1 yoki 2 element → tekshirish kerak

Nima ko'rsatdi: 2.4-bo'lim. partition — noto'g'ri formatdagi ma'lumot bilan ishlashning eng xavfsiz usuli.

Misol 3 — join va tezlik

python
"""join — birlashtirishning to'g'ri usuli."""

import time

print("=== 1. Asosiy foydalanish ===")
qismlar = ["olma", "anor", "uzum"]
ajratgichlar = [", ", "", "\n", " | ", " → "]
for a in ajratgichlar:
    print(f"  {a!r:<8}.join(...) → {a.join(qismlar)!r}")

print("\n=== 2. Har qanday iteratsiya bilan ===")
manbalar = [
    ("satr", "abc"),
    ("juftlik", ("a", "b", "c")),
    ("lug'at kalitlari", {"a": 1, "b": 2}),
    ("generator", (str(x) for x in range(3))),
    ("range", (str(x) for x in range(3))),
]
for nom, manba in manbalar:
    print(f"  {nom:<18} → {', '.join(manba)!r}")

print("\n=== 3. ⚠️ Faqat satrlar ===")
sonlar = [1, 2, 3]
try:
    ", ".join(sonlar)
except TypeError as x:
    print(f"  ', '.join([1, 2, 3]) → TypeError: {x}")

print(f"  map(str, ...)        → {', '.join(map(str, sonlar))!r}")
print(f"  generator bilan      → {', '.join(str(x) for x in sonlar)!r}")

print("\n=== 4. ⚠️ Ajratgichda chaqiriladi ===")
try:
    qismlar.join(", ")
except AttributeError as x:
    print(f"  royxat.join(', ') → AttributeError: {x}")
print(f"  ', '.join(royxat) → {', '.join(qismlar)!r}  ✅")

print("\n=== 5. Tezlik: += vs join ===")
for N in [10_000, 100_000]:
    boshlandi = time.perf_counter()
    natija = ""
    for i in range(N):
        natija += str(i)
    vaqt_qoshish = time.perf_counter() - boshlandi

    boshlandi = time.perf_counter()
    natija2 = "".join(str(i) for i in range(N))
    vaqt_join = time.perf_counter() - boshlandi

    boshlandi = time.perf_counter()
    bolaklar = []
    for i in range(N):
        bolaklar.append(str(i))
    natija3 = "".join(bolaklar)
    vaqt_royxat = time.perf_counter() - boshlandi

    print(f"\n  N = {N:,}")
    print(f"    += bilan:          {vaqt_qoshish * 1000:>8.2f} ms")
    print(f"    join(generator):   {vaqt_join * 1000:>8.2f} ms")
    print(f"    ro'yxat + join:    {vaqt_royxat * 1000:>8.2f} ms")
    print(f"    Natijalar teng:    {natija == natija2 == natija3}")

print("\n=== 6. Amaliy idiomalar ===")
matn = "  Ali   Valiyev  Toshkentdan  "
print(f"  Bo'shliqlarni normallashtirish:")
print(f"    {matn!r}")
print(f"    → {' '.join(matn.split())!r}")

print(f"\n  So'zlarni teskari:")
gap = "Salom dunyo va olam"
print(f"    {gap!r} → {' '.join(reversed(gap.split()))!r}")

print(f"\n  Chekinish qo'shish:")
kop_qator = "birinchi\nikkinchi\nuchinchi"
chekingan = "\n".join("    " + q for q in kop_qator.splitlines())
print(chekingan)

print(f"\n  Ro'yxat sifatida chiqarish:")
print("\n".join(f"    {i}. {q}" for i, q in enumerate(qismlar, 1)))

Natijaning muhim qismi:

text
=== 5. Tezlik: += vs join ===

  N = 10,000
    += bilan:              1.82 ms
    join(generator):       1.34 ms
    ro'yxat + join:        1.51 ms
    Natijalar teng:        True

  N = 100,000
    += bilan:             21.47 ms
    join(generator):      14.28 ms
    ro'yxat + join:       16.03 ms
    Natijalar teng:        True

=== 6. Amaliy idiomalar ===
  Bo'shliqlarni normallashtirish:
    '  Ali   Valiyev  Toshkentdan  '
    → 'Ali Valiyev Toshkentdan'

  So'zlarni teskari:
    'Salom dunyo va olam' → 'olam va dunyo Salom'

  Chekinish qo'shish:
    birinchi
    ikkinchi
    uchinchi

Nima ko'rsatdi: 2.6, 2.7-bo'limlar.

Misol 4 — CSV tahlilchisi

python
"""Oddiy va murakkab CSV — split ning chegaralari."""

import csv
import io
from dataclasses import dataclass

ODDIY_CSV = """ism,yosh,shahar,ball
Ali,25,Toshkent,88
Vali,30,Samarqand,92
Guli,28,Buxoro,79"""

MURAKKAB_CSV = '''ism,manzil,izoh
Ali,"Toshkent, Chilonzor",Yaxshi talaba
Vali,"Samarqand, Registon","U ""a'lo"" baho oldi"
Guli,Buxoro,'''


@dataclass
class Talaba:
    ism: str
    yosh: int
    shahar: str
    ball: int


def oddiy_oqi(csv_matn: str) -> list[Talaba]:
    """split bilan — faqat oddiy CSV uchun."""
    qatorlar = csv_matn.splitlines()
    sarlavha = [u.strip() for u in qatorlar[0].split(",")]

    natija = []
    for raqam, qator in enumerate(qatorlar[1:], 2):
        if not qator.strip():
            continue

        qiymatlar = [q.strip() for q in qator.split(",")]

        if len(qiymatlar) != len(sarlavha):
            print(f"  ⚠️ {raqam}-qator: {len(qiymatlar)} ta qiymat, "
                  f"{len(sarlavha)} kutilgan")
            continue

        yozuv = dict(zip(sarlavha, qiymatlar))
        natija.append(Talaba(
            ism=yozuv["ism"],
            yosh=int(yozuv["yosh"]),
            shahar=yozuv["shahar"],
            ball=int(yozuv["ball"]),
        ))

    return natija


print("=== 1. Oddiy CSV — split yetarli ===")
talabalar = oddiy_oqi(ODDIY_CSV)
print(f"  {'Ism':<8} {'Yosh':>5} {'Shahar':<12} {'Ball':>5}")
print("  " + "─" * 34)
for t in talabalar:
    print(f"  {t.ism:<8} {t.yosh:>5} {t.shahar:<12} {t.ball:>5}")

ortacha = sum(t.ball for t in talabalar) / len(talabalar)
print("  " + "─" * 34)
print(f"  {'OʻRTACHA':<27} {ortacha:>5.1f}")


print("\n\n=== 2. Murakkab CSV — split YETARLI EMAS ===")
print("  Kirish:")
for q in MURAKKAB_CSV.splitlines():
    print(f"    {q}")

print("\n  ❌ split bilan:")
for qator in MURAKKAB_CSV.splitlines()[1:]:
    print(f"    {qator.split(',')}")

print("\n  ✅ csv moduli bilan:")
oquvchi = csv.reader(io.StringIO(MURAKKAB_CSV))
sarlavha = next(oquvchi)
for qator in oquvchi:
    print(f"    {qator}")

print("\n  csv.DictReader bilan (eng qulay):")
oquvchi = csv.DictReader(io.StringIO(MURAKKAB_CSV))
for yozuv in oquvchi:
    print(f"    {dict(yozuv)}")


print("\n\n=== 3. Qachon split, qachon csv moduli ===")
print("""
  split yetarli:
    ✅ Ma'lumot o'zingiz yaratgan
    ✅ Qiymatlarda ajratgich yo'qligi kafolatlangan
    ✅ Tirnoq va ko'p qatorli qiymat yo'q
    ✅ Tezlik juda muhim

  csv moduli kerak:
    ✅ Tashqi manbadan kelgan ma'lumot
    ✅ Qiymatlarda vergul bo'lishi mumkin
    ✅ Tirnoqlar ishlatilgan
    ✅ Qiymat ichida yangi qator bo'lishi mumkin
    ✅ Turli lahjalar (Excel, TSV)

  Qoida: ishonchsiz ma'lumot → csv moduli.
""")


print("=== 4. CSV yozish ===")
chiqish = io.StringIO()
yozuvchi = csv.writer(chiqish)
yozuvchi.writerow(["ism", "manzil", "ball"])
yozuvchi.writerow(["Ali", "Toshkent, Chilonzor", 88])
yozuvchi.writerow(["Vali", 'U "a\'lo" oldi', 92])

print("  csv.writer natijasi:")
for q in chiqish.getvalue().splitlines():
    print(f"    {q}")

print("\n  ❌ join bilan yozish (tirnoqlar yo'q):")
print(f"    {','.join(['Ali', 'Toshkent, Chilonzor', '88'])}")
print("    ← bu qatorni qayta o'qib bo'lmaydi!")
text
=== 1. Oddiy CSV — split yetarli ===
  Ism       Yosh Shahar        Ball
  ──────────────────────────────────
  Ali         25 Toshkent        88
  Vali        30 Samarqand       92
  Guli        28 Buxoro          79
  ──────────────────────────────────
  O'RTACHA                     86.3


=== 2. Murakkab CSV — split YETARLI EMAS ===
  Kirish:
    ism,manzil,izoh
    Ali,"Toshkent, Chilonzor",Yaxshi talaba
    Vali,"Samarqand, Registon","U ""a'lo"" baho oldi"
    Guli,Buxoro,

  ❌ split bilan:
    ['Ali', '"Toshkent', ' Chilonzor"', 'Yaxshi talaba']
    ['Vali', '"Samarqand', ' Registon"', '"U ""a\'lo"" baho oldi"']
    ['Guli', 'Buxoro', '']

  ✅ csv moduli bilan:
    ['Ali', 'Toshkent, Chilonzor', 'Yaxshi talaba']
    ['Vali', 'Samarqand, Registon', 'U "a\'lo" baho oldi']
    ['Guli', 'Buxoro', '']

=== 4. CSV yozish ===
  csv.writer natijasi:
    ism,manzil,ball
    Ali,"Toshkent, Chilonzor",88
    Vali,"U ""a'lo"" oldi",92

  ❌ join bilan yozish (tirnoqlar yo'q):
    Ali,Toshkent, Chilonzor,88
    ← bu qatorni qayta o'qib bo'lmaydi!

Nima ko'rsatdi: 2.8-bo'lim. split — kuchli, lekin chegarasi bor. Ishonchsiz ma'lumot uchun tayyor kutubxona.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"split() va split(" ") bir xil" Butunlay boshqa: bo'sh elementlar va ketma-ket bo'shliqlar
""".split(",") bo'sh ro'yxat beradi" [''] — bir elementli ro'yxat
"split("\n") qatorlarga bo'ladi" Windows fayllarida \r qoladi. splitlines() ishlating
"join ro'yxat metodi" Ajratgich metodi: ", ".join(royxat)
"join sonlarni o'zi aylantiradi" Yo'q — map(str, ...) kerak
"partition va split(x, 1) bir xil" partition doim 3 element, split 1 yoki 2
"+= bilan satr qurish normal" join doim to'g'ri tanlov
"split(",") CSV uchun yetarli" Tirnoqli qiymatlarda buziladi. csv moduli kerak

6. Keng tarqalgan xatolar va yechimlari

1. Bo'sh qatordan ValueError

python
ism, yosh = qator.split(",")            # ❌ bo'sh qatorda xato

if not qator.strip():                   # ✅
    continue
qismlar = qator.split(",")
if len(qismlar) != 2:
    continue
ism, yosh = qismlar

2. split(" ") bilan ortiqcha bo'sh elementlar

python
sozlar = matn.split(" ")                # ❌ ketma-ket bo'shliqlarda bo'sh element
sozlar = matn.split()                   # ✅

3. Windows qator oxiri

python
qatorlar = matn.split("\n")             # ❌ '\r' qoladi
qatorlar = matn.splitlines()            # ✅

4. join ga sonlar

python
", ".join([1, 2, 3])                    # ❌ TypeError
", ".join(map(str, [1, 2, 3]))          # ✅

5. join ni ro'yxatda chaqirish

python
royxat.join(", ")                       # ❌ AttributeError
", ".join(royxat)                       # ✅

6. maxsplit ni unutish

python
nom, qiymat = "a: b: c".split(":")      # ❌ ValueError — 3 element
nom, qiymat = "a: b: c".split(":", 1)   # ✅
nom, _, qiymat = "a: b: c".partition(":")   # ✅ eng xavfsiz

7. Fayl kengaytmasini split bilan

python
"arxiv.tar.gz".split(".")[-1]           # ✅ 'gz' — ishlaydi
"arxiv.tar.gz".split(".", 1)            # ❌ ['arxiv', 'tar.gz']
"arxiv.tar.gz".rsplit(".", 1)           # ✅ ['arxiv.tar', 'gz']

from pathlib import Path                # ✅ eng yaxshi
Path("arxiv.tar.gz").suffix             # '.gz'

8. Tirnoqli CSV

python
qator.split(",")                        # ❌ tirnoq ichidagi vergulda buziladi
csv.reader(...)                         # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 4.6/4.7-darslar: formatlash — join bilan birga
  • 5-qism: for bilan qatorlarni qayta ishlash
  • 6-qism: ro'yxatlar, zip, lug'at yaratish
  • 10-qism: generatorlar — join bilan samarali ishlash
  • 16-qism: fayl o'qish, csv moduli, kodlash
  • 15-qism: re.split() — murakkab ajratgichlar
  • 20-qism: HTTP sarlavhalari, URL tahlili
  • 24-qism: Pandas — CSV ni professional o'qish

8. Eng yaxshi amaliyotlar

  1. Erkin matn uchun split(), aniq format uchun split(x). Ikki rejim farqini har doim eslang.

  2. Qatorlarga bo'lish uchun splitlines(). split("\n") Windows fayllarida buziladi.

  3. Noto'g'ri format kutilsa partition ishlating. Natija uzunligi kafolatlangan — tekshiruv shart emas.

  4. join ni doim += dan afzal ko'ring. Tezroq va niyat aniqroq.

  5. map(str, ...) yoki generator bilan aylantiring. join faqat satrlar bilan ishlaydi.

  6. Bo'sh qatorlarni oldindan filtrlang. if not qator.strip(): continue.

  7. Ishonchsiz CSV uchun csv moduli. split(",") tirnoqli qiymatlarda buziladi.

  8. Fayl yo'llari uchun pathlib. rsplit("/", 1) — eskirgan usul.


9. Amaliy topshiriq

Vazifa 1: Natijani bashorat qiling

python
1.  "a b".split()
2.  "a  b".split(" ")
3.  " a ".split()
4.  " a ".split(" ")
5.  "".split()
6.  "".split(",")
7.  "a,,b".split(",")
8.  "a\r\nb".split("\n")
9.  "a\r\nb".splitlines()
10. "a=b=c".partition("=")
11. "abc".partition("=")
12. "abc".rpartition("=")
13. "a:b:c".split(":", 1)
14. "a.b.c".rsplit(".", 1)
Javoblar
  1. ['a', 'b']
  2. ['a', '', 'b']
  3. ['a']
  4. ['', 'a', '']
  5. []
  6. ['']
  7. ['a', '', 'b']
  8. ['a\r', 'b']
  9. ['a', 'b']
  10. ('a', '=', 'b=c')
  11. ('abc', '', '')
  12. ('', '', 'abc')
  13. ['a', 'b:c']
  14. ['a.b', 'c']

Vazifa 2: Xatolarni tuzatish

python
1.  ism, yosh = qator.split(",")
2.  qatorlar = matn.split("\n")
3.  natija = royxat.join(", ")
4.  matn = ", ".join([1, 2, 3])
5.  sozlar = gap.split(" ")
6.  kengaytma = fayl.split(".")[1]
Javoblar
python
1.  ism, _, yosh = qator.partition(",")
    # yoki tekshiruv bilan

2.  qatorlar = matn.splitlines()

3.  natija = ", ".join(royxat)

4.  matn = ", ".join(map(str, [1, 2, 3]))

5.  sozlar = gap.split()

6.  kengaytma = fayl.rsplit(".", 1)[-1]
    # yoki: Path(fayl).suffix

Vazifa 3: Sozlama o'quvchi

2-misoldagi sozlamani_oqi() ni kengaytiring:

  1. [bo'lim] sarlavhalarini qo'llab-quvvatlasin (INI format)
  2. Qiymat turini aniqlasin (true/false → bool, raqam → int)
  3. Ichma-ich lug'at qaytarsin: {"server": {"host": "localhost", "port": 8000}}

Vazifa 4: So'z statistikasi

Matn berilgan. Hisoblang:

  1. So'zlar soni
  2. Noyob so'zlar soni (registrsiz)
  3. Eng ko'p uchraydigan 5 ta so'z
  4. O'rtacha so'z uzunligi
  5. Eng uzun gap (nuqta bo'yicha bo'ling)

Vazifa 5: URL so'rov parametrlarini tahlil qilish

python
sorov = "id=42&nom=Ali&shahar=Toshkent&bosh=&id=43"

Lug'atga aylantiring. Diqqat:

  • Takrorlangan kalitlar (id ikki marta) — ro'yxat qiling
  • Bo'sh qiymatlar (bosh=) — saqlang
  • Qiymatsiz kalitlar (&flag&) — None qiling
Yechim
python
def sorovni_tahlil(sorov: str) -> dict:
    natija: dict = {}

    for juftlik in sorov.split("&"):
        if not juftlik:
            continue

        kalit, ajratgich, qiymat = juftlik.partition("=")
        if not kalit:
            continue

        qiymat = qiymat if ajratgich else None

        if kalit in natija:
            if not isinstance(natija[kalit], list):
                natija[kalit] = [natija[kalit]]
            natija[kalit].append(qiymat)
        else:
            natija[kalit] = qiymat

    return natija

Haqiqiy ishda urllib.parse.parse_qs() ishlating (20-qism).

Vazifa 6: CSV — ikki usulda

4-misoldagi MURAKKAB_CSV ni:

  1. split bilan o'qishga urinib ko'ring — nima buziladi?
  2. csv.DictReader bilan o'qing
  3. Ikkalasining natijasini solishtiring

Vazifa 7: O'ylash

Nega join ro'yxat metodi emas, ajratgich metodi?

Javob

Uch sabab:

  1. join har qanday iteratsiya bilan ishlaydi — ro'yxat, juftlik, to'plam, lug'at, generator, satr. Agar u ro'yxat metodi bo'lganida, har bir turga alohida qo'shish kerak bo'lardi.

  2. Natija — satr, kirish — istalgan narsa. Metod natija turiga tegishli bo'lgani mantiqiy.

  3. Faqat satrlar bilan ishlaydi. [1, 2].join(", ") "ishlashi kerakdek" tuyulardi, lekin sonlar bilan ishlamaydi. Ajratgichda chaqirish bu cheklovni aniqroq qiladi.

Guido van Rossum bu haqda yozgan: bu — ataylab qilingan qaror, garchi boshida g'alati tuyulsa ham. Bir necha kun ishlatgandan keyin tabiiy bo'lib qoladi.

Nimani mustahkamlaydi: 2.1, 2.2, 2.4, 2.5, 2.6, 2.8-bo'limlar.


Xulosa

Bu darsda bo'lish va birlashtirish metodlarini o'rgandik.

Eng muhim uch fikr:

  1. split() va split(x) — butunlay boshqa xatti-harakat. Argumentsiz shakl bo'shliqlarni birlashtiradi va bo'sh element qaytarmaydi; argument bilan har bir uchrashuv alohida ajratgich. "".split(",") [''] beradi — bo'sh ro'yxat emas.

  2. partition natija uzunligini kafolatlaydi. Doim uch element — noto'g'ri formatdagi ma'lumot bilan ishlashda split(x, 1) dan xavfsizroq.

  3. join ajratgichda chaqiriladi va faqat satrlar bilan ishlaydi. ", ".join(map(str, sonlar)). Va u += dan doim afzal — tezroq hamda niyat aniqroq.

Keyingi darsda eski formatlash usullarini ko'ramiz: % operatori va .format(). Ular eskirgan, lekin mavjud kodda uchraydi va ba'zi joyda (masalan, logging) hali ham afzal.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
4.5-dars: Metodlar — bo'lish va birlashtirish — IlmHamroh