Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 281 – Schleifenzähler-Iteration mit range und xrange

Autor:
Magnus Lie Hetland <magnus at hetland.org>
Status:
Abgelehnt
Typ:
Standards Track
Erstellt:
11-Feb-2002
Python-Version:
2.3
Post-History:


Inhaltsverzeichnis

Zusammenfassung

Dieser PEP beschreibt noch eine weitere Möglichkeit, den Schleifenzähler in for-Schleifen freizulegen. Er schlägt im Grunde vor, die Funktionalität der Funktion indices() aus PEP 212 in die bestehenden Funktionen range() und xrange() aufzunehmen.

Bekanntmachung

Beim Kommentieren der enumerate()-Funktion von PEP 279 äußerte der Autor dieses PEPs: „Ich bin sehr glücklich, dass PEP 281 dadurch veraltet wird.“ Anschließend wurde PEP 279 in Python 2.3 übernommen.

Am 17. Juni 2005 stimmte der BDFL dessen Veralterung zu und wies den PEP hiermit zurück. Zur Dokumentation fand er einige der Beispiele etwas grell im Erscheinungsbild.

>>> range(range(5), range(10), range(2))
[5, 7, 9]

Motivation

Es ist oft wünschenswert, über die Indizes einer Sequenz zu iterieren. PEP 212 beschreibt mehrere Wege, dies zu tun, einschließlich der Hinzufügung einer integrierten Funktion namens `indices`, die konzeptionell wie folgt definiert ist:

def indices(sequence):
    return range(len(sequence))

Unter der Annahme, dass das Hinzufügen von Funktionalität zu einer bestehenden integrierten Funktion weniger aufdringlich sein mag als das Hinzufügen einer neuen integrierten Funktion, schlägt dieser PEP vor, diese Funktionalität zu den bestehenden Funktionen range() und xrange() hinzuzufügen.

Spezifikation

Es wird vorgeschlagen, dass alle drei Argumente der integrierten Funktionen range() und xrange() Objekte mit einer Länge sein dürfen (d. h. Objekte, die die Methode __len__ implementieren). Wenn ein Argument nicht als Ganzzahl interpretiert werden kann (d. h. es hat keine Methode __int__), wird stattdessen seine Länge verwendet.

Beispiele

>>> range(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(range(5), range(10))
[5, 6, 7, 8, 9]
>>> range(range(5), range(10), range(2))
[5, 7, 9]
>>> list(xrange(range(10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(xrange(xrange(10)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Number the lines of a file:
lines = file.readlines()
for num in range(lines):
    print num, lines[num]

Alternativen

Eine natürliche Alternative zur obigen Spezifikation ist es, xrange() den Zugriff auf seine Argumente auf faule Weise zu ermöglichen. Anstatt ihre Länge explizit zu verwenden, kann xrange einen Index für jedes Element des Stopp-Arguments zurückgeben, bis das Ende erreicht ist. Eine ähnliche faule Behandlung ist für die Argumente `start` und `step` wenig sinnvoll, da ihre Länge berechnet werden muss, bevor die Iteration beginnen kann. (Tatsächlich ist die Länge des `step`-Arguments erst erforderlich, wenn das zweite Element zurückgegeben wird.)

Eine Pseudo-Implementierung (nur mit dem Stopp-Argument und unter der Annahme, dass es iterierbar ist) lautet:

def xrange(stop):
    i = 0
    for x in stop:
        yield i
        i += 1

Das Testen, ob int() oder eine faule Iteration verwendet werden soll, könnte durch Prüfung auf ein Attribut __iter__ erfolgen. (Dieses Beispiel setzt die Anwesenheit von Generatoren voraus, könnte aber leicht als ein einfacher Iterator-Objekt implementiert worden sein.)

Es mag fraglich sein, ob dieses Feature wirklich nützlich ist, da man die Elemente des iterierbaren Objekts innerhalb der for-Schleife nicht über den Indexzugriff abrufen könnte.

Beispiel

# Printing the numbers of the lines of a file:
for num in range(file):
    print num # The line itself is not accessible

Eine umstrittenere Alternative (um damit umzugehen) wäre, range() wie die Funktion irange() aus PEP 212 zu verhalten, wenn es mit einer Sequenz versorgt wird.

Beispiel

>>> range(5)
[0, 1, 2, 3, 4]
>>> range('abcde')
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]

Abwärtskompatibilität

Der Vorschlag könnte zu Rückwärtskompatibilitätsproblemen führen, wenn Argumente verwendet werden, die sowohl __int__ als auch __len__ (oder __iter__ im Falle der faulen Iteration mit xrange) implementieren. Der Autor glaubt nicht, dass dies ein signifikantes Problem darstellt.


Quelle: https://github.com/python/peps/blob/main/peps/pep-0281.rst

Zuletzt geändert: 2025-02-01 08:55:40 GMT