Математический анализ. 3е издание
Скачать 4.86 Mb.
|
S = 'hello' >>> S[:: 1] 'olleh' При использовании отрицательного шага порядок применения пер вых двух границ меняется на противоположный. То есть выражение S[5:1:1] извлечет элемент со 2 по 5 в обратном порядке (результат бу дет содержать элементы последовательности со смещениями 5, 4, 3 и 2): >>> S = 'abcedfg' >>> S[5:1: 1] 'fdec' Пропуск элементов и изменение порядка их следования – это наиболее типичные случаи использования операции получения среза с тремя пределами. За более подробной информацией вам следует обратиться к руководству по стандартной библиотеке языка Python или поэкспе риментировать в интерактивной оболочке – это расширит ваши пред ставления о срезах по сравнению с объемом, который мы можем охва тить здесь. Мы еще вернемся к операции получения среза с тремя пре делами далее в этой книге, когда будем рассматривать ее в соединении с оператором цикла for. Инструменты преобразования строк Один из девизов языка Python – не поддаваться искушению предпола гать, что имелось в виду. Например, Python не позволит сложить стро ку и число, даже если строка выглядит как число (то есть содержит только цифры): >>> "42" + 1 TypeError: cannot concatenate 'str' and 'int' objects (TypeError: невозможно объединить объекты 'str' и 'int') В соответствии с архитектурой языка оператор + может означать и опе рацию сложения, и операцию конкатенации, вследствие чего выбор типа преобразования становится неочевидным. Поэтому интерпрета тор воспринимает такую инструкцию как ошибочную. Вообще в языке Python отвергается любая магия, которая может осложнить жизнь программиста. Как же быть, если сценарий получает число в виде текстовой строки из файла или от пользовательского интерфейса? В этом случае следует использовать инструменты преобразования, чтобы можно было интер претировать строку как число или наоборот. Например: 196 Глава 7. Строки >>> int("42"), str(42) # Преобразование в/из строки (42, '42') >>> repr(42), `42` # Преобразование в строку, как если бы она была ('42', '42') # программным кодом Функция int преобразует строку в число, а функция str преобразует число в строковое представление (по сути – в то, что выводится на эк ран). Функция repr и прежний ее эквивалент, обратные апострофы, также преобразуют объект в строковое представление, но они возвра щают объект в виде строки программного кода, который можно выпол нить, чтобы воссоздать объект (если объект – строка, то результат, вы веденный инструкцией print, будет включать кавычки, окружающие строку). Подробнее о различиях между функциями str и repr можно прочитать во врезке «Форматы представления repr и str», в главе 5. Кроме того, функции int и str изначально предназначены для выпол нения преобразований. Вы не сможете смешивать строковые и числовые типы в таких опера торах, как +, но вы можете вручную выполнить необходимые преобра зования операндов перед выполнением операции: >>> S = "42" >>> I = 1 >>> S + I TypeError: cannot concatenate 'str' and 'int' objects >>> int(S) + I # Операция сложения 43 >>> S + str(I) # Операция конкатенации '421' Придется держать в уме: срезы Повсюду в этой книге я буду включать аналогичные врезки с опи санием наиболее типичных случаев использования рассматри ваемых особенностей языка на практике. Поскольку у вас нет возможности осознать реальный потенциал языка, пока вы не увидите большую часть картины, эти врезки будут содержать множество упоминаний тем, незнакомых для вас. Поэтому вам следует воспринимать эти сведения как предварительное зна комство со способами, которые связывают абстрактные концеп ции языка с решением наиболее распространенных задач про граммирования. Например, далее вы увидите, что аргументы командной строки, переданные сценарию на языке Python при запуске, доступны в виде атрибута argv встроенного модуля sys: Строки в действии 197 Существуют похожие встроенные функции для преобразования чисел с плавающей точкой в/из строки: >>> str(3.1415), float("1.5") ('3.1415', 1.5) >>> text = "1.234E 10" >>> float(text) 1.2340000000000001e010 Позднее мы познакомимся со встроенной функцией eval – она выпол няет строку, содержащую программный код на языке Python, и пото му может выполнять преобразование строки в объект любого вида. # File echo.py import sys print sys.argv % python echo.py a b c ['echo.py', 'a', 'b', 'c'] Обычно вас будут интересовать только параметры, которые сле дуют за именем программы. Это приводит нас к типичному ис пользованию операции получения среза (или, что то же самое, извлечения подстроки): мы можем с помощью единственной ин струкции получить все элементы списка, за исключением перво го. В данном случае выражение sys.argv[1:] вернет требуемый список ['a', 'b', 'c']. После этого список можно обрабаты вать по своему усмотрению, не заботясь о присутствии имени программы в начале. Кроме того, операция получения среза часто используется для удаления лишних символов из строк, считываемых из файлов. Если известно, что строки всегда завершаются символом новой строки (символ \n), его можно удалить однимединственным вы ражением – line[:1], которое возвращает все символы строки, кроме последнего (нижняя граница по умолчанию принимается равной 0). В обоих случаях операция извлечения подстроки обеспечивает логику выполнения, которую в низкоуровневых языках программирования пришлось бы реализовывать явно. Обратите внимание: для удаления символа новой строки часто предпочтительнее использовать функцию line.rstrip, потому что она не повреждает строки, в которых отсутствует символ но вой строки в конце, – типичный случай при создании текстовых файлов некоторыми текстовыми редакторами. Операция извле чения подстроки применима, только если вы полностью увере ны, что строки завершаются корректным образом. 198 Глава 7. Строки Функции int и float преобразуют только числа, но это ограничение оз начает, что они обычно выполняют эту работу быстрее (и безопаснее, потому что они не принимают программный код произвольного выра жения). Как было показано в главе 5, выражение форматирования строки также обеспечивает возможность преобразования чисел в стро ки. Форматирование будет обсуждаться ниже, в этой же главе. Преобразование кодов символов Возможно также выполнить преобразование одиночного символа в его целочисленный код ASCII, для чего нужно передать этот символ функ ции ord – она возвращает фактическое числовое значение соответст вующего байта в памяти. Обратное преобразование выполняется с по мощью функции chr, она получает целочисленный код ASCII и преоб разует его в соответствующий символ: >>> ord('s') 115 >>> chr(115) 's' Эти функции можно применить ко всем символам строки в цикле. Они могут также использоваться для реализации своего рода строковой ма тематики. Например, чтобы получить следующий по алфавиту сим вол, его можно преобразовать в число и выполнить математическое действие над ним: >>> S = '5' >>> S = chr(ord(S) + 1) >>> S '6' >>> S = chr(ord(S) + 1) >>> S '7' Следующий пример преобразования представляет собой альтернативу встроенной функции int, по крайней мере для односимвольных строк, для преобразования строки в целое число: >>> int('5') 5 >>> ord('5') ord('0') 5 Такие преобразования могут использоваться в сочетании с оператором цикла – для получения целочисленных значений из строковых пред ставлений двоичных чисел – в каждой итерации текущее значение ум ножается на 2 и затем к нему прибавляется числовое значение следую щей цифры: >>> B = '1101' >>> I = 0 >>> while B: Строки в действии 199 ... I = I * 2 + (ord(B[0]) ord('0')) ... B = B[1:] >>> I 13 Оператор побитового сдвига влево (I << 1) мог бы дать тот же эффект, что и операция умножения на 2. Но, пока мы еще не познакомились с циклами, оставим реализацию этого упражнения как есть. Изменение строк Помните термин «неизменяемая последовательность»? Слово «неиз меняемая» означает, что вы не можете изменить содержимое самой строки в памяти (то есть невозможно изменить элемент строки, выпол нив присваивание по индексу): >>> S = 'spam' >>> S[0] = "x" Возникает ошибка! Тогда каким образом в языке Python производить изменение тексто вой информации? Чтобы изменить строку, необходимо создать новую строку с помощью таких операций, как конкатенация и извлечение подстроки, и затем, если это необходимо, присвоить результат перво начальному имени: >>> S = S + 'SPAM!' # Чтобы изменить строку, нужно создать новую >>> S 'spamSPAM!' >>> S = S[:4] + 'Burger' + S[ 1] >>> S 'spamBurger!' Первый пример добавляет подстроку в конец строки S с помощью опе рации конкатенации. В действительности здесь создается новая стро ка, которая затем присваивается имени S, но вы можете представить себе это действие как «изменение» первоначальной строки. Второй пример замещает четыре символа шестью новыми – с помощью опера ций извлечения подстроки и конкатенации. Как будет показано далее в этой главе, похожего эффекта можно добиться с помощью строково го метода replace. Вот как это выглядит: >>> S = 'splot' >>> S = S.replace('pl', 'pamal') >>> S 'spamalot' Как и всякая операция, создающая новую строку, строковые методы создают новые строковые объекты. Если вам необходимо сохранить эти объекты, вы можете присвоить их переменной. Создание нового объекта строки для каждого изменения – операция не столь неэффек 200 Глава 7. Строки тивная, как может показаться, – вспомните, в предыдущей главе гово рилось, что интерпретатор автоматически производит сборку мусора (освобождает память, занятую неиспользуемыми строковыми объек тами), поэтому новые объекты повторно используют память, ранее за нятую прежними значениями. Интерпретатор Python во многих слу чаях работает гораздо быстрее, чем можно было бы ожидать. Наконец, дополнительно существует возможность сборки текстовых значений с помощью выражений форматирования строк: >>> 'That is %d %s bird!' % (1, 'dead') # Напоминает функцию sprintf в языке C That is 1 dead bird! Это очень мощная операция! В следующем разделе рассказывается о том, как она работает. Форматирование строки В языке Python имеется двухместный оператор %, предназначенный для работы со строками (вы можете вспомнить, что для чисел он еще является оператором деления по модулю или получения остатка от де ления). Когда этот оператор применяется к строкам, он играет роль функции sprintf в языке C и обеспечивает простой способ форматиро вания значений в строке согласно заданной строке формата. Проще го воря, оператор % обеспечивает возможность компактной записи про граммного кода, выполняющего множественную подстановку строк. Чтобы отформатировать строку, требуется: 1. Слева от оператора % указать строку формата, содержащую один или более спецификатор формата, каждый из которых начинается с символа % (например, %d). 2. Справа от оператора % указать объект (или объекты, в круглых скобках), которые будут подставляться на место спецификатора (или спецификаторов) в левой части выражения. Например, в последнем примере предыдущего раздела мы видели, что целое число 1 подставляется на место спецификатора %d в строке фор мата, расположенной в левой части выражения, а строка "dead" под ставляется на место спецификатора %s. В результате получается новая строка, которая содержит эти две подстановки. Строго говоря, выражения форматирования строк не являются абсо лютно необходимыми – все, что можно сделать с их помощью, точно так же можно сделать с помощью серии преобразований и операций конкатенации. Однако операция форматирования позволяет объеди нить множество шагов в одной инструкции. Мощные возможности этой операции заслуживают того, чтобы рассмотреть еще несколько примеров: >>> exclamation = "Ni" Форматирование строки 201 >>> "The knights who say %s!" % exclamation 'The knights who say Ni!' >>> "%d %s %d you" % (1, 'spam', 4) '1 spam 4 you' >>> "%s %s %s" % (42, 3.14159, [1, 2, 3]) '42 3.14159 [1, 2, 3]' В первом примере строка "Ni" подключается к целевой строке слева, замещая спецификатор %s. Во втором примере в целевую строку встав ляются три значения. Обратите внимание: когда вставляется более од ного значения, в правой части выражения их необходимо сгруппиро вать с помощью круглых скобок (то есть создать из них кортеж). В третьем примере также вставляются три значения – целое число, объект числа с плавающей точкой и объект списка, но, обратите вни мание, что в левой части выражения всем значениям соответствует спецификатор %s, который соответствует операции преобразования в строку. Объекты любого типа могут быть преобразованы в строку (это происходит, например, при выводе на экран), поэтому для любого объ екта может быть указан спецификатор %s. Вследствие этого вам не при дется выполнять специальное форматирование, в большинстве случаев вам достаточно будет знать только о существовании спецификатора %s. Имейте в виду, что выражение форматирования всегда создает новую строку, а не изменяет строку, расположенную в левой части. Посколь ку строки являются неизменяемыми, этот оператор вынужден рабо тать именно таким способом. Как уже говорилось ранее, если вам тре буется сохранить полученный результат, присвойте его переменной. Дополнительные возможности форматирования строки Для реализации более сложного форматирования в выражениях форма тирования можно использовать любые спецификаторы формата, пред ставленные в табл. 7.3. Большинство из них окажутся знакомы про граммистам, использовавшим язык C, потому что операция форматиро вания строк в языке Python поддерживает все наиболее типичные спе цификаторы формата, которые допускается использовать в функции printf языка C (в отличие от которой выражение в языке Python возвра щает результат, а не выводит его на экран). Некоторые спецификаторы из табл. 7.3 предоставляют альтернативные способы форматирования данных одного и того же типа, например, %e, %f и %g обеспечивают аль тернативные способы форматирования чисел с плавающей точкой. Фактически спецификаторы формата в левой части выражения под держивают целый набор операций преобразования с достаточно слож ным собственным синтаксисом. В общем виде синтаксис использова ния спецификатора формата выглядит следующим образом: %[(name)][flags][width][.precision]code 202 Глава 7. Строки Таблица 7.3. Спецификаторы формата Символ спецификатора формата (code) из табл. 7.3 располагается в са мом конце. Между символом % и символом спецификатора можно до бавлять следующую информацию: ключ в словаре (name); список фла гов (flags), которые могут определять, например, признак выравнива ния (), знак числа (+), наличие ведущих нулей (0); общую ширину по ля и число знаков после десятичной точки и многое другое. Полное описание синтаксиса спецификаторов формата вы найдете в стандартном руководстве по языку Python, а сейчас для демонстра ции наиболее типичных случаев их использования приведем несколь ко примеров. В первом примере сначала применяется форматирование целого числа с параметрами по умолчанию, а затем целое число выво дится в поле шириной в шесть символов, с выравниванием по левому краю и с дополнением ведущими нулями: >>> x = 1234 >>> res = "integers: ...%d...% 6d...%06d" % (x, x, x) >>> res 'integers: ...1234...1234 ...001234' Спецификаторы %e, %f и %g отображают числа с плавающей точкой раз ными способами, как демонстрируется в следующем примере: >>> x = 1.23456789 >>> x Спецификатор Назначение %s Строка (или любой объект) %r s , но использует функцию repr, а не str %c Символ %d Десятичное (целое) число %i Целое число %u Целое число без знака %o Восьмеричное целое число %x Шестнадцатеричное целое число %X x , но шестнадцатеричные цифры возвращаются в верхнем ре гистре %e Число с плавающей точкой в экспоненциальной форме %E e , но алфавитные символы возвращаются в верхнем регистре %f Число с плавающей точкой в десятичном представлении %g Число с плавающей точкой e или f %G Число с плавающей точкой E или f %% Символ % Форматирование строки 203 1.2345678899999999 >>> '%e | %f | %g' % (x, x, x) '1.234568e+000 | 1.234568 | 1.23457' Для чисел с плавающей точкой можно реализовать дополнительные эффекты форматирования, указав необходимость выравнивания по ле вому краю, знак числа, ширину поля и число знаков после десятичной точки. Для простых задач можно было бы использовать простые функ ции преобразования чисел в строки с применением выражения форма тирования или встроенной функции str, продемонстрированной ранее: >>> '% 6.2f | %05.2f | %+06.1f' % (x, x, x) '1.23 | 01.23 | +001.2' >>> "%s" % x, str(x) ('1.23456789', '1.23456789') Форматирование строк из словаря Операция форматирования позволяет также использовать в специфи каторах формата ключи словаря, который указывается в правой части выражения, для извлечения соответствующих значений. Мы пока не много говорили о словарях, поэтому следующий пример демонстриру ет самый простой случай: >>> "%(n)d %(x)s" % {"n":1, "x":"spam"} '1 spam' В данном случае (n) и (x) в строке формата ссылаются на ключи в сло варе в правой части выражения и служат для извлечения соответст вующих им значений. Этот прием часто используется в программах, создающих код разметки HTML или XML, – вы можете построить сло варь значений и затем подставить их все одним выражением формати рования, которое использует ключи: >>> |