2010-09-19 2 views

Antwort

168

Für jeden Python-Behälter C, ist die Erwartung, dass

for item in C: 
    assert item in C 

ganz gut passieren - nicht Sie es erstaunlich finden, wenn ein Gefühl der in (die Schleife Klausel) hatte eine ganz andere Bedeutung von der anderen (die Anwesenheitskontrolle)? Ich würde es sicher tun! Es funktioniert natürlich auf diese Weise für Listen, Mengen, Tupeln, ...

Also, wenn C ist ein Wörterbuch, wenn in waren Schlüssel/Wert-Tupel in einer for Schleife erhalten, dann, nach dem Prinzip des geringsten Erstaunen, in müsste auch ein solches Tupel wie sein linker Operand im Containment-Check nehmen.

Wie nützlich wäre das? Ziemlich nutzlos in der Tat, im Grunde machen if (key, value) in C ein Synonym für if C.get(key) == value - das ist ein Scheck, den ich glaube, ich habe, durchgeführt, oder wollte ausführen, selten 100-mal mehr als das, was tatsächlich if k in Cbedeutet, die Überprüfung der Anwesenheit des Schlüssels nur und den Wert vollständig ignorieren.

Auf der anderen Seite, eine Schleife zu wollen nur auf Tasten ist durchaus üblich, zB:

for k in thedict: 
    thedict[k] += 1 

den Wert würde helfen, auch nicht besonders:

for k, v in thedict.items(): 
    thedict[k] = v + 1 

tatsächlich etwas weniger klar und weniger prägnant. (Beachten Sie, dass items die ursprüngliche Schreibweise der "richtigen" Methoden war, um Schlüssel/Wert-Paare zu erhalten: Leider war das zu der Zeit, als solche Accessoren ganze Listen zurückgaben, um "nur Iterieren" zu unterstützen, musste eine alternative Schreibweise sein eingeführt, und iteritems war es - in Python 3, wo Abwärtskompatibilität Einschränkungen mit früheren Python-Versionen stark geschwächt wurden, wurde es wieder items).

+2

Sehr klare Erklärung. Ich denke, ich muss etwas mehr unter die Haube von Python schauen. Wie die "in" - und "für x in" -Operatoren funktionieren, ist immer noch ein bisschen Magie für mich. – Falmarri

+0

@Falmarri, Ich werde mich freuen, auf einer konzeptionellen Ebene zu erklären (keine Notwendigkeit, in C-Quelle zu graben ;-), wenn Sie eine andere Frage dazu stellen!) –

+0

Nun, ich bin ein C++ Programmierer, also wahrscheinlich in C graben könnte hilfreicher sein =] Wie die Operatoren in Python funktionieren, ist für mich ein wenig unintuitiv (zumindest von einem niedrigen Verständnisniveau). – Falmarri

9

Meine Vermutung: die vollständige Tupel verwenden sei intuitiver für Looping, aber vielleicht weniger zum Testen für die Mitgliedschaft mit in.

if key in counts: 
    counts[key] += 1 
else: 
    counts[key] = 1 

Dieser Code würde wirklich nicht, wenn Sie beiden Schlüssel und Wert für in angeben müssen. Es fällt mir schwer, mir einen Anwendungsfall vorzustellen, in dem Sie prüfen würden, ob sowohl der Schlüssel als auch der Wert im Wörterbuch enthalten sind. Es ist viel natürlicher, nur die Schlüssel zu testen.

# When would you ever write a condition like this? 
if (key, value) in dict: 

Jetzt ist es nicht notwendig, dass die in Betreiber und for ... in über die gleichen Einzelteile arbeiten. Implementierungsweise sind sie verschiedene Operationen (vs. __iter__). Aber diese kleine Inkonsistenz wäre etwas verwirrend und, naja, inkonsequent.

+0

Gegeben, dass für jede andere Art von Built-in iterable, die ich mir vorstellen kann, 'x in foo' nur dann, wenn' i' in 'für i in foo' den Wert von 'x' an einem bestimmten Punkt annimmt Ich würde sagen, dass es eine sehr __huge__ Inkonsequenz wäre. – aaronasterling

Verwandte Themen