Justworks.ru

16Фев/119

Python Kickstart: целочисленное деление и списки

С чего начать изучение Python? Если с английским все в порядке, то рекомендую The Python Tutorial. На русском можно почитать «Язык программирования Python».

Из печатных книг ничего посоветовать не могу. Просмотрел в книжном магазине: «Python. Подробный справочник» Дэвида Бизли и «Программирование на Python 3. Подробное руководство» Марка Саммерфилда. На первый взгляд книги вполне адекватные, но цена кусается.

Пересказывать учебники не буду, предлагаю разобрать несколько примеров. Начнем!

Пример №1:

# coding: utf-8
 
if __name__ == '__main__':
    pass

Строка «# coding: utf-8» указывает, что файл сохранен в кодировке UTF-8. Рекомендую раз и навсегда отказаться от остальных кодировок везде, где это возможно.

Оператор pass ничего не делает. Используется как временная затычка вместо блока кода. Перед pass стоят 4 пробела - так в Python принято выделять блоки кода.

Пример №2:

# coding: utf-8
 
# <- так выделяются комментарии
 
if __name__ == '__main__': # это тоже комментарий
    # Обратите внимание! Как правило ожидается результат = 2.5
    print 'Целочисленное деление:'
    print '5 / 2 =', 5 / 2
 
    print 'Деление, возвращающее действительное число:'
    print 5.0 / 2, '=', 5 / 2.0
    print float(5) / 2, '=', 5 / float(2)
 
    print 'Целочисленное деление действительных чисел:'
    print 5.0 // 2.0
    print float(5) // float(2)

Оператор print выводит параметры на экран и переводит строку. Параметры разделяются запятой. При выводе между параметрами добавляется пробел. Чтобы print не переводил строку, нужно в конце строки поставить запятую:

print 'No <br>, please!',

Если аргументы у оператора / целые числа, то производится целочисленное деление. Достаточно часто возникает ошибка, когда вместо обычного деления выполняется целочисленное. Бывают сложные случаи:

# coding: utf-8
 
if __name__ == '__main__':
    a = 5
    b = 2
 
    # Здесь мы не знаем, что a и b - целые числа
    print 'a / b =', a / b

Если в приведенном примере a и b чаще всего действительные числа, то такую ошибку достаточно трудно отловить. Решается она так:

# coding: utf-8
 
if __name__ == '__main__':
    a = 5
    b = 2
 
    # Здесь мы не знаем, что a и b - целые числа
    print 'a / b =', float(a) / b # Всегда преобразуем a к действительному числу

В Python 3 такое поведение исправили, см. PEP 238. Этот пример хорошо демонстрирует, как разработчики Python работают над интуитивностью языка.

Пример №3

Важное достоинство Python - гибкие высокоуровневые структуры данных.

Начнем со списков:

# coding: utf-8
 
if __name__ == '__main__':
    # Создаем список с именем a
    a = [2, 3, 4]
    # Выводим список a
    print 'a =', a
    # Выводим нулевой элемент списка
    print a[0]
    # Выводим первый элемент списка
    print a[1]
 
    # Список может содержать любые типы данных,
    # в том числе списки
    b = ['a', 1, 'hello', [1, [2, [3]]]]
    print 'b =', b
 
    # Определяем длину списка a
    print 'Длина a =', len(a)
    # Добавляем новый элемент в конец списка a
    a.append(5)
    print 'a =', a
    # Добавляем новый элемент в начало списка a
    a.insert(0, 1)
    print a
 
    # Выводим элементы списка a, умноженные на 2
    for i in a:
        print i*2, # запятая в конце - не переводить на новую строку
 
    print
 
    for i in xrange(0, 10):
        print i,

Список — изменяемый тип данных, в который можно поместить переменную любого типа, в том числе и другой список. Пустой список задается так: []. При добавлении элемента список автоматически изменяет размер.

К элементам списка можно обращаться по индексу: a[0], a[1], ..., a[N]. Кроме того, применима операция среза: a[0:2], возвращающая список элементов между указанными индексами. Операция среза хорошо рассмотрена в книге «Язык программирования Python».

Оператор цикла for перебирает элементы из списка по одному. В теле цикла (отступ - 4 пробела!) производятся операции с конкретным элементом из списка.

Оператор print без параметров выполняет переход на новую строку.

Существует функция range, которая возвращает список чисел из заданного интервала. Выше рассматривается функция xrange, которая возвращает итератор. Итератор - это некая сущность, которую можно попросить "дай следующий элемент?". В результате можно получить следующий элемент, либо узнать, что больше элементов нет. Итератор не хранит в себе все элементы.

Допустим, нам нужно посчитать сумму чисел от a до b-1:

# coding: utf-8
 
if __name__ == '__main__':
    a = 1
    b = 100000
    sum = 0
    for i in range(a, b):
        sum += i
    print 'Sum =', sum

Это плохой код. Недостаток его в том, что результат функции range - это список. А что, если b = 10000000000? В памяти будет хранится огромный список, который для данной задачи совсем не нужен! На каждом шаге цикла нам нужен только текущий элемент: 1, 2, 3... Итератор не создает списка из всех элементов, он просто последовательно отдает элементы до тех пор, пока они не закончатся.

# coding: utf-8
 
if __name__ == '__main__':
    a = 1
    b = 100000
    sum = 0
    for i in xrange(a, b):
        sum += i
    print 'Sum =', sum

Так писать правильнее. В Python 3 функция range возвращает итератор, а функцию xrange убрали из языка.

Напоследок рассмотрим нюанс:

# coding: utf-8
 
if __name__ == '__main__':
    a = [1, 2, 3]
    b = ['!', a, '!']
    print b
    a = ['A', 'A', 'A']
    print b

Тут важно понять, что список b хранит в себе не содержимое списка a, а некоторую информацию о том, где взять содержимое списка a. Поэтому когда мы изменяем список a, то мы неявно изменяем содержимое списка b.

В этом случае, очевидно, никаких изменений в списке b не произойдет:

# coding: utf-8
 
if __name__ == '__main__':
    a = [1, 2, 3]
    b = ['!', [1, 2, 3], '!']
    print b
    a = ['A', 'A', 'A']
    print b

Потому что содержимое списка a и содержимое списка b[1] никак между собой не связаны.

С приведенными примерами нужно обязательно поиграться (например, в Eclipse), а также попробовать модифицировать их.


Комментарии (9) Пинги (0)
  1. Спасибо, но я что-то не так понял? «# coding: utf-8

    if name == ‘main‘: a = 1 b = 100000 sum = 0 for i in xrange(a, b): sum += i print ‘Sum =’, sum Так писать правильнее. В Python 3 функция range возвращает итератор, а функцию xrange убрали из языка.» Если правильнее почему из 3 убрали?

    • В Python 3 xrange переименовали в range, а range убрали.

      • What lianrbtieg knowledge. Give me liberty or give me death.

      • Man oh man! I’ve got a bad feeling that Gift is the one Eric allegedly drains. How the hell does she know Eric?! Also, why does Niall hate Bellenos? I’m not sure who to trust anymore. CH is making everyone look sketchy. I’m still baffled by the interaction between Mr. C and Dermott. Once again, more questions than answers!   2 likes

      • Name * Email * Website XHTML: Vrei formatare cu taguri? Poftim:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

      • ego’m imbued, himself final plebiscite. Really uncommonly cause herself bang fixer blog that’s couplet autodidactic annex amusing, annex let it make an impression himself, ego addressee hit the clutches keen dean. Your inkling is outstanding; the come out is any that deficient populace are voice rationally regarding. I am somewhat reconciled that he stumbled at cross-purposes with this respect my pursue somewhat in re this.

  2. Результат предпоследнего примера:

    [‘!’, [1, 2, 3], ‘!’] [‘!’, [1, 2, 3], ‘!’]

    содержимое b таки не изменилось, чяднт?

    • Очевидно, это всё-таки не ссылка на массив a, но присваивание массива a второму элементу массива b.

      В примере ниже массив а присваивается повторно после изменения и только тогда выводится в составе b

      if name == ‘main‘: a = [1, 2, 3] b = [‘!’, a, ‘!’] print b a = [‘A’, ‘A’, ‘A’] b = [‘!’, a, ‘!’] print b


Оставить комментарий

Нет обратных ссылок на эту запись.