Scala-ähnliche Erfassungsoperation in Python

Background

Scalas Sammelvorgang ist cool, nicht wahr? Sie können ordentlich schreiben, ohne zusätzliche Zwischenvariablen zu erstellen.

Scala


val result = (0 to 10000)
      .filter(_ % 3 == 0)
      .map(_ + 1)
      .groupBy(_ % 10)
      .map { it =>
        val k = it._1
        val v = it._2.sum
        (k, v)
    }.toList

Dieser Code ist die Summe jeder Zahl, wenn die Zahlen von 0 bis 10000 als Vielfaches von 3 belassen und durch 1 geteilt und in Gruppen unterteilt werden. Diese Berechnung hat keine besondere Bedeutung, ist jedoch ein Beispiel, in dem der Datenverarbeitungsfluss auf sehr leicht verständliche (coole) Weise mit genau derselben Denkweise geschrieben werden kann.

Wenn ich das in Python versuche ...

Python


import itertools
result = range(0, 10001)
result = filter(lambda x: x % 3 == 0, result)
result = map(lambda x: x + 1, result)
result = map(lambda x: (x % 10, x), result)
result = sorted(result)
result = itertools.groupby(result, lambda x: x[0])
result = map(lambda x: (x[0], sum(map(lambda _: _[1], x[1]))), result)
result = list(result)

Es ist schwer zu sehen und ich kann es nicht einmal sehen. Übrigens, wenn Sie in einer Aufnahme schreiben, ohne Zwischenvariablen zu verwenden

Python


result = list(
    map(lambda x: (x[0], sum(map(lambda _: _[1], x[1]))),
        itertools.groupby(
            sorted(
                map(lambda x: (x % 10, x),
                    map(lambda x: x + 1,
                        filter(lambda x: x % 3 == 0,
                               range(0, 100001)
                        )
                    )
                ), lambda x: x[0]
            )
        )               
    )
)

Der Code mit 0 Lesbarkeit ist abgeschlossen. Sie können mit etwas aufwachen, wenn Sie dies reibungslos lesen können. Der Grund ist, dass Sie, wenn Sie in der Reihenfolge f-> g-> h verarbeiten möchten, in umgekehrter Reihenfolge wie h (g (f (x))) schreiben müssen.

Tatsächlich gibt es eine Bibliothek, die dies löst. Ja, mit toolz, scalafunctional und fn.py. In diesem Artikel sind Meinungen wie ** Write in Scala ** NG-Wörter.

Toolz, CyToolz

toolz ist eine Bibliothek, die Pythons integrierte itertools und functools erweitert, damit sie funktionaler geschrieben werden können. cytoolz ist auch eine schnellere Version davon, die in Cython neu erstellt wurde. Die darin implementierten "Pipe" - und Curled-Funktionen sind sehr nützlich. Der schreckliche Code, den ich zuvor erwähnt habe, kann wie folgt geschrieben werden:

from cytoolz.curried import *
import operator as O
result = pipe(range(0, 10001),
    filter(lambda x: x % 3 == 0),
    map(lambda x: x + 1),
    reduceby(lambda x: x % 10, O.add),
    lambda d: d.items(),
    list
)

Wie ist das? Geben Sie die Daten an, die Sie mit dem ersten Argument verarbeiten möchten, und geben Sie die Funktionen an, die Sie mit dem zweiten und den nachfolgenden Argumenten nacheinander anwenden möchten. Wenn Sie mit der R-Sprache vertraut sind, können Sie an dplyr denken. Übrigens sind die hier verwendeten "Filter", "Karten" und "Reduzieren durch" alle Curry-Karten, und "Karte (f, Daten)" wird wie "Karte (f) (Daten)" multipliziert. Sie können mit "Rohr" wie folgt verbinden. Wenn Sie die gekräuselte Version nicht verwenden, ersetzen Sie pipe durch thread_last. Die von der vorherigen Funktion verarbeiteten Daten werden nacheinander an das letzte Argument jeder Funktion übergeben.

ScalaFunctional

Wie der Name schon sagt, ist scalafunctional eine Bibliothek, mit der Sie die Scala-Sammlung ähnlich bedienen können. ~~ Wenn Sie so weit gehen möchten, fügen Sie Scala (ry ~~) hinzu. Fügen Sie in dieser Bibliothek list , dict usw. in eine dedizierte Klasse namens seq ein und verarbeiten Sie sie in einer Punktkette.

from functional import seq
result = seq(range(0, 10001)) \
    .filter(lambda x: x % 3 == 0) \
    .map(lambda x: x + 1) \
    .map(lambda x: (x % 10, x)) \
    .reduce_by_key(O.add) \
    .to_list()

Dies ist der Scala am nächsten. Python erfordert jedoch einen Backslash am Ende der Zeile, was etwas ärgerlich ist. Danach ist Pythons "Lambda" -Ausdruck nicht so flexibel wie die Scala-Funktion, daher kann es für eine komplizierte Verarbeitung erforderlich sein, die Funktion einmal zu "def". In jedem Fall ist es sehr einfach und schön.

fn.py

fn.py ist auch eine Bibliothek für die funktionale Programmierung von Python. Das größte Merkmal ist, dass es wie ein Scala-Platzhalter geschrieben werden kann.

from fn import _
result = map(_ + 1, range(10))

Sie können es einfach anstelle von "Lambda" verwenden.

f = _ + 1
f(10)

>>>
11

Es passt gut zu toolz und scalafunctional.

toolz


result = pipe(range(10),
    map(_ + 1),
    list
)

scalafunctional


result = seq(range(10)) \
    .map(_ + 1) \
    .to_list()

Übrigens scheint in IPython usw. "_" nach der Reservierung zu stehen, um die letzte Ausgabe darzustellen. Wenn Sie es dort verwenden, müssen Sie es mit einem anderen Namen "importieren".

from fn import _ as it

Zusammenfassung

Wenn Sie "toolz" und "scalafunctional" verwenden, wird die funktionale Programmierung auch in Python verbessert. scalafunctional kann genau wie Scalas Erfassungsoperation geschrieben werden. Auf der anderen Seite können Sie "Pipe" von "Toolz" verwenden, um nicht nur Erfassungsvorgänge zu schreiben, sondern auch einen vielseitigeren Datenverarbeitungsfluss. Bitte kombinieren Sie diese gut mit fn.py und genießen Sie Functional Python Life [^ pandas].

Alle diesmal verwendeten Bibliotheken werden auf GitHub veröffentlicht. Natürlich ist es auch in PyPI registriert, so dass Sie es mit pip installieren können.

[^ pandas]: Selbst mit den Standard-Pandas ist es möglich, die Verarbeitung bis zu einem gewissen Grad mit einer Punktkette mit DataFrame zu verbinden.

Recommended Posts

Scala-ähnliche Erfassungsoperation in Python
Dateioperationen in Python
Dateimanipulation mit Python
Vier Regeln für Python
Wrapping von Git-Operationen in Python
Bildverarbeitungssammlung in Python
ORC, Parkettdateivorgänge in Python
Generieren Sie eine erstklassige Sammlung in Python
Wissenschaftliche Programmierung Petit Tech Collection in Python
[Python] Verstehen Sie die Slice-Operation der Liste in Sekunden
Quadtree in Python --2
CURL in Python
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Metaanalyse in Python
Unittest in Python
Epoche in Python
Zwietracht in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Plink in Python
Konstante in Python
FizzBuzz in Python
SQLite in Python
Schritt AIC in Python
LINE-Bot [0] in Python
CSV in Python
Reverse Assembler mit Python
Reflexion in Python
Konstante in Python
nCr in Python.
Format in Python
Scons in Python 3
Puyopuyo in Python
Python in Virtualenv
PPAP in Python
Quad-Tree in Python
Reflexion in Python
Chemie mit Python
Hashbar in Python
DirectLiNGAM in Python
LiNGAM in Python
In Python reduzieren
In Python flach drücken
Führen Sie eine Entitätsanalyse mit spaCy / GiNZA in Python durch
Zusammenfassung der Excel-Operationen mit OpenPyXL in Python
Sortierte Liste in Python
Täglicher AtCoder # 36 mit Python
Clustertext in Python
AtCoder # 2 jeden Tag mit Python
Täglicher AtCoder # 32 in Python