2009-02-05 9 views
9

En Python (específicamente Python 3.0 pero no creo que importe), ¿cómo puedo escribir fácilmente un ciclo sobre una secuencia de caracteres con códigos de caracteres consecutivos? Quiero hacer algo como esto pseudocódigo:Python: ¿bucle sobre caracteres consecutivos?

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

Ejemplo: ¿qué tal una buena versión de "Pythonic" de la siguiente?

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) # 

Las líneas marcadas con # son pseudocódigo. Por supuesto reduce() es real Python!

Estimados magos (especialmente los viejos magos de barba gris), quizás puedan decir que mi idioma favorito era Pascal.

Respuesta

35

Usted tienen una constante en el módulo de cadena llamado ascii_lowercase, trate de eso:

>>> from string import ascii_lowercase 

A continuación, puede iterar sobre los personajes de esa cadena.

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

Por su pregunta pangrama, hay una manera muy sencilla para averiguar si una cadena contiene todas las letras del alfabeto. Usando ascii_lowercase como antes,

>>> def pangram(str) : 
...  return set(ascii_lowercase).issubset(set(str)) 
+0

espero de aceptable para el OP barba :) – llimllib

+0

Si también tengo que ser un mago, viviré de la barba :) Usted – sykora

+0

también puede usar <= para verificar si los conjuntos son subconjuntos: set (ascii_lowercase) <= set (str) – Moshe

8

Iterar una constante con todos los caracteres que necesita es muy Pythonic. Sin embargo, si no desea importar nada y solo está trabajando en Unicode, use los built-ins ord() y su chr inverso().

for code in range(ord('a'), ord('z') + 1): 
    print chr(code) 
+0

La versión Unicode de chr() es unichr() –

+0

Una cosa más: si desea que el rango sea inclusivo, haga > >> para el código en el rango (ord ('a'), ord ('z') + 1): \t imprimir unichr (código) –

+1

no desaconsejar importar desde el estándar lib – hop

0

me gustaría escribir una función similar a la de 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)) 
6

Hay que dejar las Pascal-ismos atrás y aprender Python con una nueva perspectiva.

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

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

Al limitarse a lo que ofrece Pascal, se está perdiendo lo que ofrece Python.

Y ... intentar evitar reduce. A menudo conduce a terribles problemas de rendimiento.


Editar. Aquí hay otra formulación; este implementa la intersección establecida.

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

Éste le proporciona una parte de la información de diagnóstico para determinar qué letras faltan en un pangrama candidato.

+0

lo siento, las expresiones del generador están en 2.4 y arriba, no 2.3 – hop

+0

@hop: no recibo el comentario. El cambio de código se ve bien, pero el comentario es opaco. –

+0

@ s.lott: escribí en el comentario al cambio en sí que los GEs funcionan en 2.3+ – hop

1

Una respuesta más abstracta sería algo así como:

>>> x="asdf" 
>>> for i in range(len(x)): 
...  print x[i] 
Cuestiones relacionadas