Ein wenig mehr Details zur Einschlussnotation von Python

Über die Einschlussnotation von Python

[nbviewer] Ebenfalls veröffentlicht unter (http://nbviewer.jupyter.org/format/slides/github/y-sama/comprehension/blob/master/comprehension.ipynb#/).

Apropos Python, es ist eine inklusive Notation. <= Vorurteile? Es ist jedoch schwierig zu lesen, wenn man sich nicht daran gewöhnt hat. Deshalb habe ich versucht, das Lesen etwas detaillierter zusammenzufassen.

Normale Listenerstellung

extension_1 = []
for i in range(10):
    extension_1.append(i)
extension_1
#>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Listeneinschlussnotation

Grundlegende Syntax [counter for counter in iterator] Ich schreibe oft zuerst nur [i für i in] und ändere es dann. Beim Generieren einer Liste, die der Erweiterung_1 in Einschlussnotation entspricht

comprehension_1= [i for i in range(10)]
comprehension_1
#>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Geschwindigkeit

Vergleichen wir die Ausführungsgeschwindigkeit, ob die Listeneinschlussnotation verwendet werden soll. Es wurde unter Verwendung von Jupyters Zellmagie %% timeit gemessen.

%%timeit
extension_1 = []
for i in range(10000):
    extension_1.append(i)
#>>> 100 loops, best of 3: 3.37 ms per loop
%%timeit
comprehension_1= [i for i in range(10000)]
#>>> 1000 loops, best of 3: 1.05 ms per loop

** Die Aufnahme von Listen macht den Code nicht nur sauberer, sondern hat auch einen Vorteil in Bezug auf die Geschwindigkeit ** Referenz: Warum ist Pythons Einschlussnotation so schnell? Es gibt zwei Hauptgründe, langsam zu sein.

Der erstere Effekt kann auch beseitigt werden, indem die Referenz aus der Schleife gedrückt wird.

%%timeit
extension_1_ = []
append=extension_1_.append
for i in range(10000):
    append(i)
#>>> 1000 loops, best of 3: 1.57 ms per loop

Es wird allgemein gesagt, dass die Ausführungsgeschwindigkeit verdoppelt wird, wenn die Liste enthalten ist, aber ungefähr 80% davon sind auf den Overhead des Aufrufteils der Append-Methode zurückzuführen.

Beim Einbeziehen von if (postfix if)

Es gibt keine Postfix if-Anweisung in Python, aber Sie können (als Ergebnis) nur die Listeneinschlussnotation schreiben.

extension_2 =[]
for i in range(10):
    if i%2==0:
        extension_2.append(i)
extension_2
#>>> [0, 2, 4, 6, 8]

Wenn Sie extension_2 in Listeneinschlussnotation umschreiben, sieht es folgendermaßen aus.

comprehension_2 = [i for i in range(10) if i%2==0]
comprehension_2
#>>> [0, 2, 4, 6, 8]

Das Ergebnis ist eine Postfix-If-Syntax, da die Inklusivnotation eine for-Klausel gefolgt von einer if-Klausel oder einer for-Klausel enthält. (Stellen Sie sich vor, Sie können den Doppelpunkt und den Einzug weglassen.)

Mit Einrückung ist das Bild wie folgt.

[
i
for i in range(10)
  if i%2==0
]

Ich werde dies in Dark Edition etwas ausführlicher erläutern. ..

%%timeit
extension_2 =[]
for i in range(10000):
    if i%2==0:
        extension_2.append(i)
#>>> 100 loops, best of 3: 4.08 ms per loop
%%timeit
comprehension_2 = [i for i in range(10000) if i%2==0]
#>>> 100 loops, best of 3: 3.15 ms per loop
%%timeit
extension_2_ =[]
append=extension_2_.append
for i in range(10000):
    if i%2==0:
        append(i)
#>>> 100 loops, best of 3: 3.81 ms per loop

** Wenn die Berechnungsrate bestimmt wird, verbessert sich die Geschwindigkeit nur um etwa 20 bis 30%, selbst wenn Sie die Listeneinschlussnotation erzwingen. ** **.

Wenn if ~ else enthalten ist (bedingter Operator)

Es ist verwirrend, aber ** wenn es eine else-Klausel enthält, ändert sich die Position von if, weil der bedingte Operator (mit anderen Worten der ternäre Operator) verwendet wird ** (Bedingte Operatoren werden erst nach Python 2.5 unterstützt.)

extension_3 =[]
for i in range(10):
    if i%2==0:
        extension_3.append(i)
    else:
        extension_3.append(str(i))
extension_3
#>>> [0, '1', 2, '3', 4, '5', 6, '7', 8, '9']
comprehension_3 = [ i if i%2==0 else str(i) for i in range(10)]
comprehension_3
# >>> [0, '1', 2, '3', 4, '5', 6, '7', 8, '9']

Es ist möglicherweise einfacher zu verstehen, wenn Sie der Meinung sind, dass dies tatsächlich gleichwertig ist

extension_3_cond =[]
for i in range(10):
    extension_3_cond.append(i) if i%2==0 else extension_3_cond.append(str(i))
extension_3_cond
#>>> [0, '1', 2, '3', 4, '5', 6, '7', 8, '9']

Ich erhalte eine Fehlermeldung, wenn ich if ~ else hinzufüge, nachdem ich durch das Schreiben eines Postfixes if gezogen wurde.

#Funktioniert nicht
[ i for i in range(10) if i%2==0 else str(i)]
#>>> SyntaxError: invalid syntax

Da, wenn ~ else ratenbestimmend ist, die Einschlussnotation nicht viel beschleunigt.

Wörterbucheinschlussnotation und Einschlussnotation festlegen

In Python2.7 oder höher können Wörterbucheinschlüsse und Satzeinschlüsse auch als andere Einschlussnotationen als Listen verwendet werden.

comprehension_dict = {str(i):i for i in range(10)}
print(comprehension_dict)
#>>> {'7': 7, '8': 8, '2': 2, '9': 9, '0': 0, '1': 1, '6': 6, '5': 5, '4': 4, '3': 3}

Es passt gut zum Reißverschluss.

label = ["kinoko", "takenoko", "suginoko"]
feature = ["yama", "sato", "mura"]
{i:j for i,j in zip(label,feature)}
#>>> {'kinoko': 'yama', 'suginoko': 'mura', 'takenoko': 'sato'}

Wenn Sie den Schlüssel und den Wert einfach wie in diesem Fall übergeben, müssen Sie die Einschlussnotation nicht verwenden. dict(zip(label,feature))

Bis zu Python2.6 werde ich Tupel zum Diktieren übergeben.

comprehension_dict2 = dict((str(i),i) for i in range(10))
print(comprehension_dict2)

Sie können auch postfix verwenden, wenn.

comprehension_dict2 = {str(i):i for i in range(10) if i%2==0}
print(comprehension_dict2)
#>>> {'8': 8, '6': 6, '2': 2, '4': 4, '0': 0}

Sie können auch bedingte Operatoren verwenden. Da es sich um einen bedingten Operator handelt, muss er in jedem Schlüssel und Wert vor und nach dem ":" beschrieben werden.

comprehension_dict3 = {str(i) if i%2==0 else i : i if i%2==0 else str(i) for i in range(10)}
print(comprehension_dict3)
#>>> {'2': 2, 1: '1', 3: '3', 5: '5', '0': 0, 7: '7', 9: '9', '6': 6, '4': 4, '8': 8}

Das funktioniert nicht. (Ich habe es vor orz gemacht)

#Funktioniert nicht
comprehension_dict4 = {str(i):i if i%2==0 else i:str(i) for i in range(10)}
#>>> SyntaxError: invalid syntax

Legen Sie die Einschlussnotation fest

Wenn Sie es in {} ohne Doppelpunkt einschließen, wird es in den Satz aufgenommen.

comprehension_set={i%5 for i in range(10)}
comprehension_set
#>>> {0, 1, 2, 3, 4}

Beachten Sie, dass {} mit null Elementen ein Wörterbuch bedeutet.

zero_set={}
type(zero_set)
# >>> dict

Generatorausdruck und Tapple-Einschlussnotation

Es ist leicht, die Syntax falsch zu verstehen, aber selbst wenn Sie sie in () einschließen, handelt es sich um einen Generatorausdruck anstelle einer Taple-Einschlussnotation.

comprehension_gen=(i%5 for i in range(10))
comprehension_gen
#>>> <generator object <genexpr> at 0x7f3000219678>

for i in comprehension_gen:print(i)
#>>> 0
#>>> 1
#>>> 2
#>>> 3
#>>> 4
#>>> 0
#>>> 1
#>>> 2
#>>> 3
#>>> 4

Es wird eher anstelle der Tupeleinschlussnotation verwendet. Im Gegensatz zur Liste werden nicht alle Elemente im Speicher gespeichert, sondern das nächste Element in der angegebenen Reihenfolge generiert. Das Schreiben ohne Verwendung der Einschlussnotation ist wie folgt, aber es ist problematisch, da Sie nur gehen können, wenn Sie eine Funktion erstellen, die einen Generator einmal generiert.

def gen_func():
    for i in range(10):
        yield i%5
extension_gen = gen_func()
extension_gen
#>>> <generator object gen_func at 0x7f3000166830>

Sie benötigen die Tupeleinschlussnotation nicht oft, aber wenn Sie sie wirklich benötigen, können Sie sie erstellen, indem Sie die Listeneinschlussnotation an die Tupelfunktion übergeben.

tuple([i for i in range(10)])
#>>> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

[Zusatz] Ich werde den Inhalt des Kommentars hinzufügen. Sie können es an den Generator übergeben, und der Generator kann die Klammern weglassen, daher denke ich, dass es leicht zu lesen ist. (Es wird wie eine Tapple-Inklusionsnotation geschrieben.)

tuple(i for i in range(10))
#>>> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

#Abkürzung für Klammern in der folgenden Syntax
tuple((i for i in range(10)))

Vergleich mit funktionaler Programmierung

Karten-, Filter- und Einschlussnotation haben ähnliche Ausgaben und werden häufig verglichen. In Python 2-Serien geben Map und Filter eine Liste zurück, sodass sie der Listeneinschlussnotation entspricht. In der Python 3-Serie werden Map- und Filterobjekte zurückgegeben, sodass sie dem Generator entsprechen.

Umschreiben mit Karte

map(lambda i:i**2,range(1,11))
# python2.Für x
#>>> [1, 4, 9, 16, 25, 36, 49, 64, 100]
# python3.Im Fall von x wird ein Iterator mit dem Namen map object zurückgegeben.
#>>> <map at 0x4570f98>

list(map(lambda i:i**2,range(1,11)))
#>>> [1, 4, 9, 16, 25, 36, 49, 64, 100]

#Wenn es sich um eine Listeneinschlussnotation handelt
[i**2 for i in range(1,11)]
#>>> [1, 4, 9, 16, 25, 36, 49, 64, 100]

Umschreiben mit Filter

filter(lambda i:i%2==1, range(1,11))
# python2.Für x
#>>> [1, 3, 5, 7, 9]
# python3.Für x wird ein Iterator namens Filter Object zurückgegeben
#>>> <filter at 0x4578a20>

list(filter(lambda i:i%2==1, range(1,11)))
#>>> [1, 3, 5, 7, 9]
#Wenn es sich um eine Listeneinschlussnotation handelt
[i for i in range(1,11) if i%2==1]
#>>> [1, 3, 5, 7, 9]

Wenn verschachtelt

map(lambda j:j**2, filter(lambda i:i%2==1, range(1,11)))
# python2.Für x
#>>> [1, 9, 25, 49, 81]
# python3.Im Fall von x wird das Filterobjekt zurückgegeben
#>>> <filter at 0x4578a20>

list(map(lambda j:j**2, filter(lambda i:i%2==1, range(1,11))))
#>>> [1, 9, 25, 49, 81]

#Wenn es sich um eine Listeneinschlussnotation handelt
[i**2 for i in range(1,11) if i%2==1]
#>>> [1, 9, 25, 49, 81]

Ich finde es einfacher, die Listeneinschlussnotation zu lesen, aber ist es eine Frage der Vertrautheit? Außerdem ist die Aufnahme von Listen im Allgemeinen schneller.

Weg zur Dunkelheit

** Nach dem Lesen dieses Abschnitts empfehlen wir Ihnen, den lesbaren Code zu lesen, um Ihren Geist zu reinigen. ** **. Ich halte es für pythonisch, keine andere mehrstufige oder bedingte Verzweigung als die grundlegende Einschlussnotation zu verwenden.

Verbinden Sie mehrere bedingte Operatoren

Verbinden Sie mehrere bedingte Operatoren Am Beispiel von Fizzbuzz sieht es so aus.

fizzbuzz=[]
for i in range(1,16):
    if i%15==0:
        fizzbuzz.append("fizzbuzz")
    elif i%3==0:
        fizzbuzz.append("fizz")
    elif i%5==0:
        fizzbuzz.append("buzz")
    else:
        fizzbuzz.append(i)
#>>> [1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz']
["fizzbuzz" if i%15==0 else "fizz" if i%3==0 else "buzz"
 if i%5==0 else i for i in range(1,16)]
#>>> [1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz']

Verschachtelt (mehrere Arrays)

Ich denke, es gibt einige Fälle, in denen Sie ein Array verschachteln möchten. Sie können dies tun, indem Sie die Listeneinschlussnotation in die Listeneinschlussnotation verschachteln.

outer_list=[]
for i in range(3):
    innter_list=[]
    for j in range(10):
        innter_list.append(j)
    outer_list.append(innter_list)
outer_list
#>>> [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
#>>>  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
#>>>  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]

#Wenn Sie in Listeneinschlussnotation schreiben
[[j for j in range(10)] for i in range(3)]
#>>> [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
#>>>  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
#>>>  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]

Wenn es um Tripel geht, wird es schwierig zu lesen, obwohl es Python ist.

Doppelschleife

Nehmen Sie als Beispiel Flatten. Es ist nicht so schwer zu lesen, wenn man es einmal verstanden hat. Auf den ersten Blick ist die Lesbarkeit deutlich eingeschränkt.

init=[[1,2,3],[4,5],[6,7]]
flatten=[]
for outer in init:
    for inner in outer:
        flatten.append(inner)
flatten
#>>> [1, 2, 3, 4, 5, 6, 7]

#Entspricht diesem
[inner for outer in init for inner in outer]
#>>> [1, 2, 3, 4, 5, 6, 7]

Lesen Sie im Grunde genommen in der Reihenfolge der for-Klausel auf der linken Seite, und das Letzte, was Sie in die Liste aufnehmen müssen, fällt Ihnen ein. Wenn Sie einrücken möchten, sieht es so aus.

[
inner
for outer in init
    for inner in outer
]
#>>> [1, 2, 3, 4, 5, 6, 7]

[Einschließlich if (postfix if) Abschnitt](http://qiita.com/y__sama/items/a2c458de97c4aa5a98e7#if%E3%82%92%E5%90%AB%E3%82%80% Ähnlich wie bei E5% A0% B4% E5% 90% 88% E5% BE% 8C% E7% BD% AEif) verhält es sich so, als würde der Doppelpunkt und der Einzug für jede for-Klausel weggelassen.

Patatoku Kashii

Durch die Kombination von Reißverschluss und Doppelschlaufe können Sie Patatoku Cassie mit einem Liner erzeugen.

patato=[]
for i in zip("Pat Auto","Taxi"):
    for j in i:
        patato.append("".join(j))
"".join(patato)
#>>> 'Patatoku Kashii'

#Wenn Sie in der Einschlussnotation schreiben
"".join(["".join(j) for i in zip("Pat Auto","Taxi") for j in i])
#>>> 'Patatoku Kashii'

#Wenn eingerückt
"".join(
  [
  "".join(j)
  for i in zip("Pat Auto","Taxi")
    for j in i
  ]
)
#>>> 'Patatoku Kashii'

Sie können auch drucken.

[print(k) for i in zip("Pat Auto","Taxi") for j in i for k in j]
#>Pa
#>Ta
#>Zu
#>Ku
#>Leistung
#>Shi
#>- -
#>- -
#>>> [None, None, None, None, None, None, None, None]
#Es gibt keinen Rückgabewert für die Druckfunktion, daher handelt es sich um eine Auswahl von None.

Mehrfachschleifen-Matching-Technik mit if-Klausel

Es ist sehr gut. Wenn Sie mehrere Arrays oder Lambda hinzufügen, ist es schön zu lesen.

import re
DIO=["U","Nutzlos","RR","Arm","Y"]

rslt=[]
for i in DIO:
    if re.match("[URY]+",i):
        for j in i:
            rslt.append(j*2)
"".join(rslt)
#>>> 'UURRRRYY'

#Einschlussnotation
"".join([j*3 for i in DIO if re.match("[URY]+",i) for j in i])
#>>> 'UUURRRRRRYYY'

#Wenn eingerückt, sieht es so aus
"".join(
  [
    j*4
    for i in DIO
      if re.match("[URY]+",i)
        for j in i
  ]
)
#>>> 'UUUURRRRRRRRYYYY'

Recommended Posts

Ein wenig mehr Details zur Einschlussnotation von Python
Python-Ausnahmebehandlung etwas bequemer
Ein bisschen mehr über FIFO
Erstellen einer Python-Umgebung auf einem Mac
Erstellen einer Python-Umgebung unter Ubuntu
Erstellen Sie eine Python-Umgebung auf dem Mac (2017/4)
Erstellen Sie eine Python3-Umgebung unter CentOS7
Ein bisschen mehr über Referenzen ~ Verwenden von Python und Java als Beispiele ~
Erstellen Sie eine Python-Umgebung unter MacOS (Catallina)
Erstellen Sie eine Python-Umgebung auf Ihrem Mac
Ein Memo mit Python2.7 und Python3 in CentOS
Kartenmietinformationen auf einer Karte mit Python
Führen Sie Python-Code in der A2019 Community Edition aus
Erstellen Sie eine Python + OpenCV-Umgebung in Cloud9
[Python] Ein Fortschrittsbalken auf dem Terminal
Python unter Windows
Twitter mit Python3
Erstellen Sie einfach eine Python 3-Ausführungsumgebung unter Windows
Erstellen Sie eine Python-Umgebung mit ansible auf centos6
Erstellen Sie eine Python-Umgebung auf einem Mac (Mountain Lion)
Folium: Visualisieren Sie Daten auf einer Karte mit Python
Erstellen Sie eine Python-Entwicklungsumgebung auf Ihrem Mac
Python auf Mac
Eine Geschichte über das Ausführen von Python auf PHP auf Heroku
[Venv] Erstellen Sie eine virtuelle Python-Umgebung unter Ubuntu
Ein Memorandum zum Berühren von Python Flask mit Heroku
Richten Sie eine Python-Entwicklungsumgebung auf Marvericks ein
Python auf Windbg
Erstellen einer Python-Umgebung auf dem Sakura VPS-Server
Entschlüsseln Sie eine unter iOS mit Python verschlüsselte Zeichenfolge
Erstellen Sie eine Python-Ausführungsumgebung unter IBM i
Visualisiere grib2 auf einer Karte mit Python (matplotlib)
Erstellen Sie eine Python-Entwicklungsumgebung auf Raspberry Pi
Ich habe ein wenig über die Klasse recherchiert
Eine kleine Geschichte, die beim Schreiben von Twilio-Anwendungen mit Python auf AWS Lambda süchtig macht
Stellen Sie Python 3.6 / Django / Postgres-Webanwendungen in Azure bereit
Erstellen Sie eine GVim-basierte Python-Entwicklungsumgebung unter Windows 10 (3) GVim8.0 und Python3.6
# 2 Erstellen Sie eine Python-Umgebung mit einer EC2-Instanz von AWS (ubuntu18.04).
Python Ver. Einführung in WebPay mit ein wenig Code
Erstellen Sie eine Python-Umgebung für maschinelles Lernen unter Mac OS
Erstellen Sie die Python-Erweiterung E-Cell 4 unter Windows 7 (64 Bit).
Memo zum Erstellen einer Python-Entwicklungsumgebung mit macOS Catalina
Bis zum Zeichnen eines 3D-Diagramms mit Python in Windows 10
Erstellen Sie eine komfortable Python 3 (Anaconda) -Entwicklungsumgebung mit Windows
Stellen Sie die Django-Anwendung in Google App Engine (Python3) bereit.
Machen Sie mit Python einen Haltepunkt auf der c-Ebene
Ich habe eine Python3-Umgebung unter Ubuntu mit direnv erstellt.
Erstellen Sie eine GVim-basierte Python-Entwicklungsumgebung unter Windows 10 (1)
So erstellen Sie eine Django (Python) -Umgebung auf Docker
Erstellen Sie eine Python-Entwicklungsumgebung unter Mac OS X.
Lesen Sie etwas mehr Arch / Arm / Boot / Compressed / Makefile
Erstellen Sie mit pyenv eine Python-Umgebung auf Ihrem Mac
Vorgehensweise zum Erstellen einer CDK-Umgebung unter Windows (Python)
Schreiben Sie in Python ein logarithmisches Histogramm auf die x-Achse
Erstellen Sie eine Python-Entwicklungsumgebung mit pyenv unter MacOS
Hinweise zur Beschleunigung des Python-Codes mit Numba