Bereich über Charakter in Python

73

Gibt es eine Möglichkeit, sich über Zeichen zu erstrecken? etwas wie das.

for c in xrange( 'a', 'z' ):
    print c

Ich hoffe ihr könnt helfen.

huan
quelle
16
Wenn Sie nur das englische Alphabet wollen, gibt es import string, string.ascii_lowercase.
Thomas K

Antworten:

96

Dies ist eine großartige Verwendung für einen benutzerdefinierten Generator:

Python 2:

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    for c in xrange(ord(c1), ord(c2)+1):
        yield chr(c)

dann:

for c in char_range('a', 'z'):
    print c

Python 3:

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    for c in range(ord(c1), ord(c2)+1):
        yield chr(c)

dann:

for c in char_range('a', 'z'):
    print(c)
Ned Batchelder
quelle
7
Wunderschönen! Beachten Sie für alle, die dies kopieren möchten, dass der Bereich (1,3) die Werte 1 und 2 (und nicht drei) iteriert, char_range ('a', 'c') jedoch 'a', 'b' und 'iteriert 'c'!
Vicmortelmans
Sie können auch den optionalen Schritt arg hinzufügen: def char_range(c1, c2, step=1)...ord(c1), ord(c2)+1, step
wjandrea
@wjandrea, funktioniert nicht ganz für negative Schritte, zB char_range('g','a',-1)gibt['g', 'f', 'e', 'd', 'c']
alancalvitti
@ Alan Schöner Fang! Sieht so aus, als wäre das die Schuld von +1 ord(c2). Also ersetzen ord(c2)+1durch ord(c2) + (1 if step > 0 else -1). Aus Gründen der Klarheit möchten Sie dies möglicherweise aus dem range()Anruf herausrechnen.
Wjandrea
1
Das Problem dabei ist, dass Sie zum Generieren von az wissen müssen, welches Zeichen nach z kommt. Nicht besonders bequem. Wahrscheinlich besser, um den Namen «Bereich» zu vermeiden (verwenden Sie stattdessen Closedrange oder Inclusiverange?)
Camion
88
import string
for char in string.ascii_lowercase:
    print char

Siehe String - Konstanten für die anderen Möglichkeiten, einschließlich Groß, Zahlen, sprachabhängigen Zeichen, die Sie alle kommen zusammen , wie string.ascii_uppercase + string.ascii_lowercasewenn Sie alle Zeichen wollen in mehreren Sätzen.

agf
quelle
25

Sie müssen die Zeichen in Zahlen umwandeln und wieder zurück.

for c in xrange(ord('a'), ord('z')+1):
    print chr(c) # resp. print unicode(c)

Aus Gründen der Schönheit und Lesbarkeit können Sie dies in einen Generator einwickeln:

def character_range(a, b, inclusive=False):
    back = chr
    if isinstance(a,unicode) or isinstance(b,unicode):
        back = unicode
    for c in xrange(ord(a), ord(b) + int(bool(inclusive)))
        yield back(c)

for c in character_range('a', 'z', inclusive=True):
    print(chr(c))

Dieser Generator kann mit inclusive=False(Standard) aufgerufen werden , um Pythons übliches Verhalten nachzuahmen, um das Endelement auszuschließen, oder mit inclusive=True(Standard), um es einzuschließen . Also mit dem Standard inclusive=False, 'a', 'z'würde umspannt nur den Bereich von azu y, ohne z.

Wenn einer a, bUnicode ist, gibt es das Ergebnis in Unicode, sonst verwendet es chr.

Es funktioniert derzeit (wahrscheinlich) nur in Py2.

glglgl
quelle
3
Sie können dies in einem Generator verstecken: siehe meine Antwort.
Ned Batchelder
2
Du meinst, es gefällt dir besser mit den Ord und Chr in deinem Gesicht? Und wenn Sie dies mehr als einmal tun müssten, würden Sie es an jedem Ort duplizieren? Seltsam ..
Ned Batchelder
Also hatte ich besser gesagt "das sieht besser aus" als "das sieht besser aus".
glglgl
12

Hier gibt es andere gute Antworten (persönlich würde ich wahrscheinlich string.lowercase verwenden), aber der Vollständigkeit halber könnten Sie map () und chr () für die ASCII-Werte in Kleinbuchstaben verwenden:

for c in map(chr, xrange(97, 123)):
   print c
GreenMatt
quelle
9

Wenn Sie eine kurze feste Liste von Zeichen haben, verwenden Sie einfach Pythons Behandlung von Zeichenfolgen als Listen.

for x in 'abcd':
    print x

oder

[x for x in 'abcd']
Dannid
quelle
6

Ich mag einen Ansatz, der so aussieht:

base64chars = list(chars('AZ', 'az', '09', '++', '//'))

Es kann sicherlich mit viel mehr Komfort implementiert werden, aber es ist schnell und einfach und sehr gut lesbar.

Python 3

Generatorversion:

def chars(*args):
    for a in args:
        for i in range(ord(a[0]), ord(a[1])+1):
            yield chr(i)

Oder wenn Sie Listenverständnisse mögen:

def chars(*args):
    return [chr(i) for a in args for i in range(ord(a[0]), ord(a[1])+1)]

Der erste ergibt:

print(chars('ĀĈ'))
<generator object chars at 0x7efcb4e72308>
print(list(chars('ĀĈ')))
['Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ']

während der zweite ergibt:

print(chars('ĀĈ'))
['Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ']

Es ist wirklich praktisch:

base64chars = list(chars('AZ', 'az', '09', '++', '//'))
for a in base64chars:
   print(repr(a),end='')
print('')
for a in base64chars:
   print(repr(a),end=' ')

Ausgänge

'A''B''C''D''E''F''G''H''I''J''K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z''a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z''0''1''2''3''4''5''6''7''8''9''+''/'
'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '+' '/' 

Warum das list()? Ohne base64charskönnte ein Generator werden (abhängig von der von Ihnen gewählten Implementierung) und kann daher nur in der allerersten Schleife verwendet werden.

Python 2

Ähnliches kann mit Python 2 archiviert werden. Es ist jedoch weitaus komplexer, wenn Sie auch Unicode unterstützen möchten. Um Sie zu ermutigen, Python 2 nicht mehr zugunsten von Python 3 zu verwenden, möchte ich hier keine Python 2-Lösung anbieten;)

Versuchen Sie heute, Python 2 für neue Projekte zu vermeiden. Versuchen Sie auch, alte Projekte zuerst auf Python 3 zu portieren, bevor Sie sie erweitern - auf lange Sicht lohnt sich die Mühe!

Die ordnungsgemäße Behandlung von Unicode in Python 2 ist äußerst komplex und es ist nahezu unmöglich, Python 2-Projekten Unicode-Unterstützung hinzuzufügen, wenn diese Unterstützung nicht von Anfang an integriert wurde.

Hinweise zum Zurückportieren auf Python 2:

  • Verwenden Sie xrangeanstelle vonrange
  • Erstellen Sie eine zweite Funktion ( unicodes?) Für die Behandlung von Unicode:
    • Verwenden Sie unichrstatt chr, um unicodestatt zurückzukehrenstr
    • Vergessen Sie nie , zu füttern unicodeStrings als argszu machen ordund Array - Index richtig funktionieren
Tino
quelle
5
for character in map(   chr, xrange( ord('a'), ord('c')+1 )   ):
   print character

Drucke:

a
b
c
sichere Kurve
quelle
5
# generating 'a to z' small_chars.
small_chars = [chr(item) for item in range(ord('a'), ord('z')+1)]
# generating 'A to Z' upper chars.
upper_chars = [chr(item).upper() for item in range(ord('a'), ord('z')+1)]

quelle
3

Inspiriert vom oberen Beitrag oben, habe ich mir Folgendes ausgedacht:

map(chr,range(ord('a'),ord('z')+1))                     
sjs7007
quelle
1

Mit der Antwort von @ ned-batchelder hier ändere ich sie ein wenig für python3

def char_range(c1, c2):
    """Generates the characters from `c1` to `c2`, inclusive."""
    """Using range instead of xrange as xrange is deprecated in Python3""" 
    for c in range(ord(c1), ord(c2)+1):
        yield chr(c)

Dann dasselbe wie in Neds Antwort:

for c in char_range('a', 'z'):
    print c

Danke Ned!

Andy K.
quelle
0

Verwenden Sie "for count in range" und chr & ord:

print [chr(ord('a')+i) for i in range(ord('z')-ord('a'))]
Erjemin
quelle
0

Listenverständnis verwenden:

for c in [chr(x) for x in range(ord('a'), ord('z'))]:
    print c
Bugalugs Nash
quelle
0

Eine weitere Option (funktioniert wie Reichweite - addiere 1, um zu stoppen, wenn du willst, dass Stopp inklusive ist)

>>> import string
>>> def crange(arg, *args):
...     """character range, crange(stop) or crange(start, stop[, step])"""
...     if len(args):
...         start = string.ascii_letters.index(arg)
...         stop = string.ascii_letters.index(args[0])
...     else:
...         start = string.ascii_letters.index('a')
...         stop = string.ascii_letters.index(arg)
...     step = 1 if len(args) < 2 else args[1]
...     for index in range(start, stop, step):
...         yield string.ascii_letters[index]
...
>>> [_ for _ in crange('d')]
['a', 'b', 'c']
>>>
>>> [_ for _ in crange('d', 'g')]
['d', 'e', 'f']
>>>
>>> [_ for _ in crange('d', 'v', 3)]
['d', 'g', 'j', 'm', 'p', 's']
>>>
>>> [_ for _ in crange('A', 'G')]
['A', 'B', 'C', 'D', 'E', 'F']
Wyrmwood
quelle
0

Ich hatte das gleiche Bedürfnis und ich benutzte dieses:

chars = string.ascii_lowercase
range = list(chars)[chars.find('a'):chars.find('k')+1]

Hoffe das wird jemandem helfen

Ayoub Aboussaad
quelle
0

Je nachdem, wie komplex der Zeichenbereich ist, kann ein regulärer Ausdruck praktisch sein:

import re
import string

re.findall("[a-f]", string.printable)
# --> ['a', 'b', 'c', 'd', 'e', 'f']

re.findall("[n-qN-Q]", string.printable)
# --> ['n', 'o', 'p', 'q', 'N', 'O', 'P', 'Q']

Dies umgeht das lästige Problem, versehentlich die Satzzeichen zwischen Zahlen, Groß- und Kleinbuchstaben in die ASCII-Tabelle aufzunehmen.

gens
quelle