Python: цикл по последовательным символам? - PullRequest
10 голосов
/ 05 февраля 2009

В Python (в частности, в Python 3.0, но я не думаю, что это имеет значение), как мне легко написать цикл над последовательностью символов, имеющих последовательные коды символов? Я хочу сделать что-то вроде этого псевдокода:

for Ch from 'a' to 'z' inclusive: #
    f(Ch)

Пример: как насчет хорошей "питонической" версии следующего?

def Pangram(Str):
    ''' Returns True if Str contains the whole alphabet, else False '''
    for Ch from 'a' to 'z' inclusive: #
        M[Ch] = False
    for J in range(len(Str)):
        Ch = lower(Str[J])
        if 'a' <= Ch <= 'z':
            M[Ch] = True
    return reduce(and, M['a'] to M['z'] inclusive) #

Строки, отмеченные #, являются псевдокодом. Конечно, limit () - это настоящий Python!

Дорогие волшебники (особенно старые, седобородые волшебники), возможно, вы можете сказать, что моим любимым языком был Паскаль.

Ответы [ 5 ]

37 голосов
/ 05 февраля 2009

У вас есть константа в строковом модуле с именем ascii_lowercase, попробуйте это:

>>> from string import ascii_lowercase

Затем вы можете перебирать символы в этой строке.

>>> for i in ascii_lowercase :
...     f(i)

Для вашего вопроса о панграмме есть очень простой способ выяснить, содержит ли строка все буквы алфавита. Используя ascii_lowercase, как и раньше,

>>> def pangram(str) :
...     return set(ascii_lowercase).issubset(set(str))
10 голосов
/ 05 февраля 2009

Итерация константы со всеми необходимыми символами - очень Pythonic. Однако, если вы не хотите импортировать что-либо и работаете только в Юникоде, используйте встроенные функции ord () и ее обратную функцию chr ().

for code in range(ord('a'), ord('z') + 1):
     print chr(code)
6 голосов
/ 05 февраля 2009

Вы должны оставить позади Паскализмы и изучать Python с новой точки зрения.

>>> ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> def pangram( source ):
    return all(c in source for c in ascii_lowercase)

>>> pangram('hi mom')
False
>>> pangram(ascii_lowercase)
True

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

И ... старайтесь избегать reduce. Это часто приводит к ужасным проблемам с производительностью.


Edit. Вот еще одна формулировка; этот реализует пересечение множества.

>>> def pangram( source ):
>>>     notused= [ c for c in ascii_lowercase if c not in source ]
>>>     return len(notused) == 0

Этот блок дает вам диагностическую информацию для определения того, какие буквы отсутствуют в панграмме кандидата.

2 голосов
/ 16 августа 2011

Более абстрактный ответ будет выглядеть примерно так:

>>> x="asdf"
>>> for i in range(len(x)):
...     print x[i]
0 голосов
/ 05 февраля 2009

Я бы написал функцию, похожую на Python range

def alpha_range(*args):
  if len(args) == 1:
    start, end, step = ord('a'), ord(args[0]), 1
  elif len(args) == 2:
    start, end, step = ord(args[0]), ord(args[1]), 1
  else:
    start, end, step = ord(args[0]), ord(args[1]), args[2]
  return (chr(i) for i in xrange(start, end, step))
...