Програмиране с Python: Списъци, n-торки, множества
Author: Стефан Кънев, Николай Бачийски и Димитър Димитров

# Списъци, n-торки, речници, множества

### „ Програмиране с Python“, ФМИ

### Стефан Кънев, Николай Бачийски & Димитър Димитров

#### 06.03.2008г.

# Колекции в Python

- Списъци
- n-торки
- Множества

# Списъци

- Подредена колекция от обекти
- Отделните елементи се достъпват чрез индекс — цяло число
- Променлива дължина — няма нужда да я определяме преди използване
- Могат да бъдат променяни на място
- Могат да съдържат обекти от различни типове
- Списъците могат да се влагат един в друг
- Записват се като поредица от обекти, разделени със запетаи и оградени в средни скоби:
  `["Foo", [baba, 8, []], "Baz"]`

# Списъци — примери

    >>> words = ["Foo", "Bar", "Baz", "Qux"]
    >>> primes = [2, 3, 5, 7, 11, 13, 17, 19]
    >>> asl = [21, "Male", "Sofia"]
    >>> dish = ["spam", "bacon", "sausage", "spam"]

    >>> actor = "Eric Idle"
    >>> sketch = "Spam"
    >>> stuff = [actor, 42, sketch]
    >>> print stuff
    ['Eric Idle', 42, 'Spam']

    >>> stuff[1] = stuff
    >>> print stuff
    ['Eric Idle', [...], 'spam']
    >>> stuff[1][0] = 2**9
    >>> print stuff
    [512, [...], 'Spam']

# Списъци — основни операции

- Намиране на дължина — `len(списък)`

      >>> len(["Foo", "Bar", "Baz", "Qux"])
      4

- Събиране — `+`

      >>> [1, 2] + [3, 4]
      [1, 2, 3, 4]

- Съдържа ли се обект в списък — `in`

      >>> "Spam" in ["Eggs", "Bacon", "Spam"]
      True

# Списъци — индексиране и отрязъци

    >>> cheese = ['Red Leicester', 'Cheddar', 'Emmental', 'Mozzarella', 'Tilsit', 'Limburger']
    >>> cheese[0]
    'Red Leicester'
    >>> cheese[-1]
    'Limburger'
    >>> cheese[1:4]
    ['Cheddar', 'Emmental', 'Mozzarella']
    >>> cheese[1:-1]
    ['Cheddar', 'Emmental', 'Mozzarella', 'Tilsit']
    >>> cheese[1:]
    ['Cheddar', 'Emmental', 'Mozzarella', 'Tilsit', 'Limburger']
    >>> cheese[:3]
    ['Red Leicester', 'Cheddar', 'Emmental']
    >>> cheese[0:6:2]
    ['Red Leicester', 'Emmental', 'Tilsit']
    >>> cheese[::2]
    ['Red Leicester', 'Emmental', 'Tilsit']
    >>> cheese[::-1]
    ['Limburger', 'Tilsit', 'Mozzarella', 'Emmental',
    'Cheddar', 'Red Leicester']

# Списъци — промяна

    >>> food = ['eggs', 'bacon', 'spam']
    >>> print food
    ['eggs', 'bacon', 'spam']
    >>> food[1] = 'sausage'
    >>> print food
    ['eggs', 'sausage', 'spam']
    >>> food.append('spam')
    >>> print food
    ['eggs', 'sausage', 'spam', 'spam']
    >>> food.append(['манджа', 'грозде'])
    >>> print food
    ['eggs', 'sausage', 'spam', 'spam', ['манджа', 'грозде']]

# Списъци — промяна (2)

    >>> food = ['ham', 'eggs']
    >>> food.extend(['bacon', 'spam'])
    >>> print food
    ['ham', 'eggs', 'bacon', 'spam']
    >>> del food[1]
    >>> print food
    ['ham', 'bacon', 'spam']
    >>> food[:2] = ['I', 'want', 'more']
    >>> print food
    ['I', 'want', 'more', 'spam']
    >>> del food[:3]
    >>> print food
    ['spam']

# Списъци — методи

    >>> knights = ["Arthur", "Galahad"]
    >>> knights.append('Bedevere')
    >>> knights
    ['Arthur', 'Galahad', 'Bedevere']
    >>> knights.extend(['Lancelot', 'Robin')
    # Може и knigts += ['Lancelot', 'Robin']
    >>> knights
    ['Arthur', 'Galahad', 'Bedevere', 'Lancelot', 'Robin']
    >>> knights.sort()
    >>> knights
    ['Arthur', 'Bedevere', 'Galahad', 'Lancelot', 'Robin']
    >>> knights.reverse()
    >>> knights
    ['Robin', 'Lancelot', 'Galahad', 'Bedevere', 'Arthur']
    >>> someone = knights.pop()
    >>> print someone
    'Arthur'
    >>> print knights
    ['Robin', 'Lancelot', 'Galahad', 'Bedevere']

# Списъци — методи (2)

    >>> food = ['spam', 'eggs', 'sausage', 'spam', 'bacon', 'spam']
    >>> food.index('eggs')
    1
    >>> food.index('hamandeggs')
    ValueError: list.index(x): x not in list

    >>> food.count('spam')
    3
    >>> food.count('bacon')
    1
    >>> food.insert(2, 'spam')
    ['spam', 'eggs', 'spam', 'sausage', 'spam', 'bacon', 'spam']

# Списъци — обхождане

- Обхождането на списъци става с конструкцията `for`
- Синтаксисът изглежда така:

      for [име] in [нещо-за-обхождане]:
          [блок код]

- Тук `in` е част от синтаксиса, не проверка за притежание
- `[нещо-за-обхождане]` може да е както литерал — `[1, 2, 3]` така и име, например `knights`
- Повече за `for` — след малко

# Списъци — обхождане

    >>> numbers = [1, 2, 3, 5, 7, 11, 13]
    >>> answer = 0
    >>>
    >>> for n in numbers:
    	answer += n
    	print "Adding %d to the answer" % n
    >>> print answer
    42

# n-торки (tuples)

- n-торките са неизменяеми (immutable) списъци
- Записват се по същия начин, но с малки скоби, вместо средни:
  `primes = (2, 3, 5, 7, 11, 13)`
`primes = 2, 3, 5, 7, 11, 13` `prime = (2,)`, иначе ще се сметне за израза `2`
- Можете да ги индексирате и slice-вате, но не и променяте:

      >>> primes[0]
      2
      >>> primes[1:4]
      (3, 5, 7)
      >>> primes[5] = 17

      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: 'tuple' object does not support item assignment

- Нямат никакви методи
- Могат да се влагат:
  `("Foo", "Bar", ("Spam",), ("More, "Spam"))`

# n-торки (tuples) (2)

- Ако имате n-торка, съдържаща само имена от лявата страна на присвояване, може да постигнете интересни ефекти:

      >>> (a, b) = 1, 2
      >>> print a
      1

- Всъщност скобите не са задължителни:

      >>> a, b = 1, 2
      >>> a, b = b, a
      >>> print a
      2
      >>> print b
      1

- Или:

      >>> numbers = (1, 2, 3)
      >>> a, b, c = numbers

# Сравняване на списъци/n-торки

Списъците/n-торките се сравняват лексигокрафски

    >>> (1, 2) < (1, 3)
    True
    >>> ("Foo", 2) < (1, 2)
    False
    >>> (1, 2) < (1, 2, 3)
    True
    >>> [1, 2] < [1, 3]
    True
    >>> (1, 2) < [1, 3] # tuple vs. list
    False

# Множества (set)

- Всеки елемент може да се съдържа не повече от веднъж
- Създават се със `set([списък/n-торка])`
- Ненаредена колекция!
- Пример:

      >>> numbers = set([1, 2, 3, 8, 2])
      >>> numbers
      set([8, 1, 2, 3])
      >>> 2 in numbers
      True
      >>> 4 in numbers
      False
      >>> numbers.add(4)
      >>> 4 in numbers
      True
      >>> numbers.remove(1)