Angenommen, ich habe eine Python-Liste, die Bereiche für einige Variablen darstellt:
conditions = [['i', (1, 5)], ['j', (1, 2)]]
Dies stellt dar, dass die Variable i
zwischen 1 und 5 liegt und innerhalb dieser Schleife j
zwischen 1 und 2 liegt. Ich möchte ein Wörterbuch für jede mögliche Kombination:
{'i': 1, 'j': 1}
{'i': 1, 'j': 2}
{'i': 2, 'j': 1}
{'i': 2, 'j': 2}
{'i': 3, 'j': 1}
{'i': 3, 'j': 2}
{'i': 4, 'j': 1}
{'i': 4, 'j': 2}
{'i': 5, 'j': 1}
{'i': 5, 'j': 2}
Der Grund ist, dass ich über sie iterieren möchte. Aber weil der gesamte Speicherplatz zu groß ist, möchte ich nicht alle generieren, speichern und dann diese Liste von Wörterbüchern durchlaufen. Ich habe überlegt, das folgende rekursive Verfahren zu verwenden, aber ich brauche Hilfe bei dem yield
Teil. Wo soll es sein Wie vermeide ich verschachtelte Generatoren?
def iteration(conditions, currentCondition, valuedIndices):
if currentCondition == len(conditions):
yield valuedIndices
else:
cond = conditions[currentCondition]
index = cond[0]
lim1 = cond[1][0]
lim2 = cond[1][1]
for ix in range(lim1, lim2 + 1):
valuedIndices[index] = ix
yield iteration(conditions, currentCondition + 1, valuedIndices)
Jetzt möchte ich in der Lage sein:
for valued_indices in iteration(conditions, 0, {}):
...
yield
mityield from
in der allerletzten Zeile Ihrer Funktion.Antworten:
Dies ist ein Fall, in dem es möglicherweise einfacher ist, einen Schritt zurückzutreten und neu zu beginnen.
Beginnen wir damit, die Schlüssel und die Intervalle mit einem bekannten Trick zu trennen
zip
:(Die Entsprechung zwischen den beiden behält die ursprüngliche Paarung bei;
intervals[i]
ist das Intervall für die Variablekeys[i]
für allei
.)Lassen Sie uns nun aus diesen Intervallen geeignete Bereichsobjekte erstellen
Wir können das Produkt dieser
range
Objekte berechnendie Sie als die Werte erkennen sollten, die für jedes Diktat verwendet werden sollen. Sie können jeden dieser Werte mit den Schlüsseln komprimieren, um einen geeigneten Satz von Argumenten für den
dict
Befehl zu erstellen . Zum Beispiel:Wenn wir dies alles zusammenfassen, können wir das Produkt durchlaufen, um es nacheinander zu produzieren
dict
und es zu erhalten.quelle
Sie können vielleicht ein wenig mit einem internen Generatorverständnis vereinfachen und
yield from
es:benutzen als:
quelle
dict_factory(*args)
damals ... Hmmm ...Ich bin nicht sicher, ob Sie speziell die Rekursion verwenden müssen oder nicht, aber Sie könnten diese mithilfe der itertools-Produktmethode generieren, um alle Kombinationen zu generieren. Dies ist so geschrieben, dass Sie 1 bis n Bedingungen haben können und es weiterhin funktionieren und Sie Artikel für Artikel zurücksenden sollte.
AUSGABE
quelle