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.


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)

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.


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.


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

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']

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

5
for character in map(   chr, xrange( ord('a'), ord('c')+1 )   ):
   print character

Drucke:

a
b
c

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

3

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

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

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!


0

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

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

0

Listenverständnis verwenden:

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

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']

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


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.