it-swarm.com.de

Einzeilig verschachtelt für Schleifen

Schrieb diese Funktion in python, das eine Matrix transponiert:

def transpose(m):
    height = len(m)
    width = len(m[0])
    return [ [ m[i][j] for i in range(0, height) ] for j in range(0, width) ]

Dabei wurde mir klar, dass ich nicht vollständig verstehe, wie für Schleifen geschachtelte einzelne Zeilen ausgeführt werden. Bitte helfen Sie mir beim Verständnis, indem Sie die folgenden Fragen beantworten:

  1. In welcher Reihenfolge wird diese for-Schleife ausgeführt?
  2. Wenn ich eine dreifach verschachtelte for-Schleife hätte, welche Reihenfolge würde sie ausführen?
  3. Was wäre gleich gleich ungeschachtelt für Schleife?

Gegeben,

[ function(i,j) for i,j in object ]
  1. Welcher Typ muss object sein, um dies für die Schleifenstruktur zu verwenden?
  2. In welcher Reihenfolge werden i und j Elementen im Objekt zugewiesen?
  3. Kann es durch eine andere for loop Struktur simuliert werden?
  4. Kann diese for-Schleife mit einer ähnlichen oder anderen Struktur für loop verschachtelt werden? Und wie würde es aussehen?

Zusätzliche Informationen sind ebenfalls erwünscht.

83
Asher Garland

Die beste Informationsquelle ist das offizielles Python Tutorial zu Listenverständnissen . Listenverständnisse sind fast die gleichen wie für Schleifen (sicherlich kann jedes Listenverständnis als für geschrieben werden) -loop), aber sie sind oft schneller als die Verwendung einer for-Schleife.

Schauen Sie sich dieses längere Listenverständnis aus dem Tutorial an (der Teil if filtert das Verständnis, nur Teile, die die if-Anweisung bestehen, werden in den letzten Teil des Listenverständnisses übergeben (hier (x,y)):

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Dies ist genau das Gleiche wie bei dieser verschachtelten for-Schleife (und wie im Lernprogramm angegeben, beachten Sie, dass die Reihenfolge von for und if identisch ist).

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Der Haupt-Unterschiedzwischen einem Listenverständnis und einer for-Schleife besteht darin, dass der letzte Teil der for-Schleife (wo Sie etwas tun) am Anfang und nicht am Ende steht.

Auf zu Ihren Fragen:

Welcher Typ muss object sein, um dies für die Schleifenstruktur zu verwenden?

Ein iterabel . Jedes Objekt, das eine (endliche) Menge von Elementen erzeugen kann. Dazu gehören Container, Listen, Sets, Generatoren usw.

In welcher Reihenfolge werden i und j Elementen im Objekt zugewiesen?

Sie werden in genau derselben Reihenfolge zugewiesen, in der sie aus jeder Liste generiert wurden, als wären sie in einer verschachtelten for-Schleife (für Ihr erstes Verständnis würden Sie 1 Element für i erhalten, dann jeden Wert von j, 2. Element in i, dann jeder Wert von j usw.)

Kann es durch eine andere for loop Struktur simuliert werden?

Ja, bereits oben gezeigt.

Kann diese for-Schleife mit einer ähnlichen oder anderen Struktur für loop verschachtelt werden? Und wie würde es aussehen?

Sicher, aber es ist keine gute Idee. Hier erhalten Sie zum Beispiel eine Liste mit Zeichenlisten:

[[ch for ch in Word] for Word in ("Apple", "banana", "pear", "the", "hello")]
138
Jeff Tratner

Vielleicht interessieren Sie sich für itertools.product , das eine iterative Ausgabe von Tupeln von Werten aus allen iterablen Werten liefert, die Sie übergeben haben. Das heißt, itertools.product(A, B) liefert alle Werte der Form (a, b), Wobei die a Werte von A und die b Werte stammen von B. Zum Beispiel:

import itertools

A = [50, 60, 70]
B = [0.1, 0.2, 0.3, 0.4]

print [a + b for a, b in itertools.product(A, B)]

Dies druckt:

[50.1, 50.2, 50.3, 50.4, 60.1, 60.2, 60.3, 60.4, 70.1, 70.2, 70.3, 70.4]

Beachten Sie, dass das letzte an itertools.product Übergebene Argument das "innere" ist. Im Allgemeinen ist itertools.product(a0, a1, ... an) gleich [(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]

27
Lynn

Zunächst verwendet Ihr erster Code keine for-Schleife an sich, sondern ein Listenverständnis .

  1. Wäre gleichbedeutend mit

    für j im Bereich (0, Breite): für i im Bereich (0, Höhe): m [i] [j]

  2. Ähnlich wie bei Loops verschachtelt es im Allgemeinen von rechts nach links. Die Syntax für das Listenverständnis ist jedoch komplexer.

  3. Ich bin nicht sicher, was diese Frage stellt


  1. Jedes iterable Objekt, das iterable Objekte liefert, die genau zwei Objekte liefern (was für ein Mundvoll - d. H. [(1,2),'ab'] wäre gültig)

  2. Die Reihenfolge, in der sich das Objekt bei der Iteration ergibt. i geht zum ersten Ertrag, j zum zweiten.

  3. Ja, aber nicht so hübsch. Ich glaube, es ist funktional gleichbedeutend mit:

     l = list () 
     für i, j im Objekt: 
     l.append (function (i, j)) 
    

    oder besser noch map :

    map(function, object)
    

    Aber natürlich müsste die Funktion i, j selbst holen.

  4. Ist das nicht die gleiche Frage wie 3?

3
korylprince