Учебная страница курса биоинформатики,
год поступления 2011
Словари, кортежи, параметры командной строки
Содержание
Словари
Синонимов названию масса: словари (dict, dictionary), отображения (map, mapping), хэш-таблицы (hash table), ассоциативные массивы (associative array) – все эти названия понимаются более-менее одинаково.
Суть простая: питон хранит список пар ключ '(уникальный!)' -> значение, и умеет по ключу добыть значение, записать новое значение, добавить в список этих пар новую или удалить существующую.
Пишется это так:
1 >>> x = dict() # так оно называется с т.з. питона
2 >>> x = {} # лучше писать всегда так
3 >>> x[1] = 2 # добавили элемент в словарь
4 >>> print(x)
5 { 1: 2 }
6 >>> x["hello"] = "world" # добавили ещё элемент в словарь
7 >>> print(x)
8 { 'hello': 'world', 1: 2 }
9 >>> print(x[1])
10 2
11 >>> x[1] = 3 # изменили элемент словаря
12 { 1: 3, 'hello': 'world' }
13 >>> # мы никогда не знаем, в каком порядке хранятся значения в словаре
14 >>> del x['hello'] # удалили элемент словаря
15 >>> y = { 1: 2, 'hello': "world" } # а можно создавать словарь сразу так
Если мы хотим перебрать всё содержимое словаря, мы можем воспользоваться циклом for. Когда словарь попадает в то место, где питон ожидает списка, то он интерпретируется как список всех ключей (в произвольном порядке). Примеры:
Вопрос на засыпку: как распечатать содержимое словаря в порядке возрастания ключей?
Питон старается преследовать насколько это осмысленно (но не более) простоту и универсальность записи. Обратите внимание, что основной синтаксис работы со словарями такой же, как и со списками: хранилище[место в хранилище] = значение или значение = хранилище[место в хранилище]:
Вопрос на засыпку: чем в данном случае отличается dict от list? (Два простых примера: как выглядят присваивание за границы существующего, цикл? Какие ещё отличия можете придумать?)
Метод get()
За дальнейшей информацией о том, как работать со словарями, я вас отправляю к хелпам (интересного там разве что update, get, setdefault, pop), но про один метод всё-таки расскажу:
Метод d.get(key,value) для словаря читает элемент по ключу key. (То же самое, что квадратные скобочки после имени словаря). Однако, если элемента в словаре нету, то он не выдаст ошибку, а вернёт свой второй аргумент value (или None, если он опущен).
Соответственно, довольно часто встречается такая идиома:
Метод get никогда не меняет словарь. Аналогичная штука, которая записывает значение в словарь, зовётся setdefault.
Тупли (кортежи, tuples)
По сути это то же самое, что и список, только тупли нельзя менять.
Если нам нужен тупль из этого элемента, то это можно сделать только так:
Такая вот ограниченная и простая штука.
Тупли можно использовать в качестве ключей в словарях (пример — разреженная матрица).
Двойное присваивание
Есть такая удобная штука - tuple unpacking:
или:
1 >>> a, b, c = 1, 2, 3
Тут полезно понимать следующее: сначала питон полностью исполняет то, что в правой части присваивания (собирает кортеж), а потом распаковывает получившийся котеж слева. Это значит, что мы можем в правой и в левой части использовать одни и те же переменные:
Возврат нескольких значений из функции
Ту же идею, что и двойное присваивание, можно использовать для того, чтобы возвращать из функции несколько значений:
Разбор командной строки с помощью optparse
Когда мы вызываем программу через командную строку, мы можем также указывать ее параметры (если они есть).
Например, вспомним команду ls. Ее можно вызвать с различными параметрами.
ls -lR ls --long --recursive ls -l -R
Все три записи выше равнозначны между собой.
ls --sort=time # параметры могут принимать какое-то значение ls a.txt b.txt
Если параметр написан через знак дефиса, то он называется именованным, иначе – позиционным.
В переменной sys.argv содержится список строк - все то, что было написано в командной строке (разделенное по пробелам).
Например, если мы напишем маленькую программку test_argv.py:
И запустим ее с какими-нибудь параметрами, то получится так:
Для того, чтобы автоматизировать разбор командной строки подобно программе ls, надо импортировать библиотеку optparse.
parser - это так называемый объект-разборщик (далее будем называть его просто парсером).
Разберем это на примере программы сортировки (пусть будет называться sort.py).
Пусть для нее можно будет указывать три параметра:
-r --reverse -w --word -a --sort-alg
Для этого надо прописать:
1 import optparse
2 import sys
3 parser=optparse.OptionParser()
4 parser.add_option('-w', '--word', help='word number to sort by', type='int')
5 parser.add_option('-r', '--reverse', action='store_true', help='reverse sort order')
6 parser.add_option('-a', '--sort-alg', dest='alg', help='sorting algorithm; can be "qsort" (qsort) or "merge" (merge-sort)', type='string', default='qsort')
7 options, args=parser.parse_args()
8 print options.word
9 print options.reverse
10 print options.alg # значение положилось в options.alg, как это указано в 'dest'
11 print args
12 print sys.argv
Итак, парсер будет разбирать слово, стоящее после записи '-w' ('--word'), '-a' ('--sort-alg') или '-r' ('--reverse'). Для '-w' оно должно быть целым числом, для '-a' - строкой и по умолчанию равно 'qsort'.
Фраза action='store_true' означает, что данный параметр является флагом. Если бы этого не было, то параметр нёс бы какое-то значение.
В args будут записываться все то, что парсер не смог разобрать.
Рассмотрим диалог с командной строкой:
$ python sort.py None None qsort [] ['sort.py'] $ python sort.py -r -w 1 -a merge a.txt 1 True merge ['a.txt'] ['sort.py', '-r', '-w', '1', '-a', 'merge', 'a.txt'] $ python sort.py --help Usage: sort.py [options] Options: -h, --help show this help message and exit -w WORD, --word=WORD word number to sort by -r, --reverse reverse sort order -a ALG, --sort-alg=ALG sorting algorithm; can be "qsort" (qsort) or "merge" (merge-sort) $ python sort.py -x sort.py [options] sort.py: error: no such option: -x
Мы можем захотеть как-то реагировать на отсутствие значения для обязательного параметра (например, параметра '-w'):
1 import optparse
2 import sys
3 parser=optparse.OptionParser()
4 parser.add_option('-w', '--word', help='word number to sort by', type='int')
5 parser.add_option('-r', '--reverse', action='store_true', help='reverse sort order')
6 parser.add_option('-a', '--sort-alg', dest='alg', help='sorting algorithm; can be "qsort" (qsort) or "merge" (merge-sort)', type='string', default='qsort')
7 options, args=parser.parse_args()
8 print options.word
9 if not options.word:
10 parser.error('Word number is not given')
Тогда диалог с командной строкой будет выглядеть так:
$ python sort.py None Usage: sort.py [options] sort.py: error: Word number is not given $ python sort.py -w 3 3