събота, 17 януари 2009 г.

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

„ Програмиране с Python“, ФМИ
Стефан Кънев & Николай Бачийски
05.03.2007г.



Колекции в Python

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

Списъци

* Подредена колекция от обекти
* Достъпва се чрез итерация или отместване
* Променлива дължина
* Могат да бъдат променяни на място
* Може да съдържа обекти от различни типове
* Списъците могат да се влагат един в друг
* Записват се като поредица от литерали или имена, разделени със запетаи и оградени в средни скоби:
["Foo", "Bar", "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']

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

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

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

* Конкатенация — +

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

* Проверка за съдържание — in

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

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

>>> cheeses = ['Red Leicester', 'Cheddar', 'Emmental', 'Mozzarella',
'Tilsit', 'Limburger']
>>> cheeses[0]
'Red Leicester'
>>> cheeses[-1]
'Limburger'

>>> cheeses[1:4]
['Cheddar', 'Emmental', 'Mozzarella']
>>> cheeses[1:-1]
['Cheddar', 'Emmental', 'Mozzarella', 'Tilsit']
>>> cheeses[1:]
['Cheddar', 'Emmental', 'Mozzarella', 'Tilsit', 'Limburger']
>>> cheeses[:3]
['Red Leicester', 'Cheddar', 'Emmental']

>>> cheeses[0:6:2]
['Red Leicester', 'Emmental', 'Tilsit']
>>> cheeses[::2]
['Red Leicester', 'Emmental', 'Tilsit']
>>> cheeses[::-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']

>>> del food[1]
>>> print food
['eggs', 'spam', '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.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

n-орки (tuples)

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

>>> primes[0]
2
>>> primes[1:4]
(3, 5, 7)
>>> primes[5] = 17
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment

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

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

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

>>> (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] False Множества (set) * Съдържат всеки елемент само веднъж * Конструират се със set([списък]) * Пример: >>> numbers = set([1, 2, 3])
>>> 1 in numbers
True
>>> 4 in numbers
False
>>> numbers.add(4)
>>> 4 in numbers
True
>>> numbers.remove(1)

Речници

* Речниците са структури, които съпоставят един обект (ключ) на друг (стойност) - например име -> телефонен номер или град -> държава.
* Други имена на тази структура - хеш, карта (map) и асоциативен масив.
* Ключът трябва да е immutable (число, низ, n-орка)
* Синтаксисът в Python е следния:

>>> languages = {
'Spain': 'Spanish',
'Great Britain': 'English',
'Italy': 'Italian',
'Mexico': 'Spanish',
'France': 'French',
'USA': 'English',
}

* Достъпът става със средни скоби:

>>> print languages['Mexico']
'Spanish'

Речници (2)

>>> capitals = {
'Germany': 'Berlin',
'France': 'Paris',
'Brazil': 'Rio de Janeiro',
'Malaysia': 'Kuala Lumpur',
}
>>> print capitals['Brazil']
'Rio de Janeiro'

>>> capitals['Brazil'] = 'Brazil'
>>> print capitals['Brazil']
'Brazil'

>>> capitals['Sweden'] = 'Stockholm'
>>> print capitals['Sweden']
'Stockholm'

>>> del capitals['Malaysia']
>>> print capitals['Malaysia']
Traceback (most recent call last):
File "", line 1, in
NameError: name 'capitals' is not defined

Речници - методи

>>> capitals = {
'Germany': 'Berlin',
'France': 'Paris',
'Brazil': 'Rio de Janeiro',
'Sweden': 'Stockholm',
}

>>> capitals.get('Assyria')
None
>>> capitals.get('Assyria', "I don't know")
"I don't know"

>>> capitals.has_key('Sweden')
True

>>> capitals.keys()
['Brazil', 'France', 'Germany', 'Sweden']

>>> capitals.values()
['Berlin', 'Paris', 'Brazil', 'Stockholm']


Речници - методи (2)

>>> numbers = {
"One": "I",
"Two": "II",
}

>>> numbers.items()
[('One', 'I'), ('Two', 'II')]

>>> numbers.update({"Three": "III", "Four": "IV"})
{'Four': 'IV', 'Three': 'III', 'Two': 'II', 'One': 'I'}

>>> numbers.pop('Four')
'IV'
>>> numbers
{'Three': 'III', 'Two': 'II', 'One': 'I'}

>>> numbers.popitem()
{'Three': 'III'}
>>> numbers.popitem()
{'One': 'I'}

Два други начина за създаване на речник

* Чрез наименовани параметри към конструктура (не питайте):

>>> dict(france="Paris", italy="Rome")
{'italy': 'Rome', 'france': 'Paris'}

* Чрез списък от двойки

>>> dict([('One', 'I'), ('Two', 'I')])
{'Two': 'I', 'One': 'I'}

Отново към for цикъла

* Синтаксис:

for [променлива] in [колекция]
[блок]

* Оператора break излиза от цикъла
* Оператора continue прекъсва текущата итерация и продължава изпълнението на цикъла от следващия елемент

... range() ...

range(x, y) връща списък от числата в интервала [x, y)


>>> range(0, 10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(0, 10, 2)
[0, 2, 4, 6, 8]
>>> range(10, 0, -1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

Пример за for

for n in range(0, 20):
if n % 2: continue
print n
if n > 10: break

Произвежда следния резултат:

0
2
4
6
8
10
12

Пример

roman = {1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}
numbers = [2, 3, 5]

for n in numbers:
print n, "is", roman[n]

Получава:

2 is II in Roman numbers
3 is II in Roman numbers
5 is V in Roman numbers

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

Публикуване на коментар