Ich wollte so etwas einmal ausprobieren
path
, aber das ist auch angebrachtf.py
def write(lines):
print 'write:', lines
csv.py
# -*- coding: utf-8 -*-
import f
def as_kvs(rows):
keys = rows[0]
value_rows = rows[1:]
return [dict(zip(keys, value_row)) for value_row in value_rows]
def write_first_one_or_empty(rows, sort_key, filter_key, filter_value, write_key):
#Machen Sie mehrere kv
kvs = as_kvs(rows)
#Nach angegebenem Schlüssel sortieren
_sorted = sorted(kvs, key=lambda row: row[sort_key])
#Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
_filtered = filter(lambda row: row[filter_key] == filter_value, _sorted)
if 0 < len(_filtered):
#Extrahieren Sie die erste Zeile mit dem angegebenen Schlüssel
_mapped_one = map(lambda row: row[write_key], _filtered)[0]
#Schreiben
f.write([_mapped_one])
else:
#Leere Datei erstellen
f.write([])
def write_all_or_empty(rows, filter_key, filter_value, write_key):
#Machen Sie mehrere kv
kvs = as_kvs(rows)
#Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
_filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
if _filtered:
#Extrahieren Sie alle Zeilen mit dem angegebenen Schlüssel
_mapped = map(lambda row: row[write_key], _filtered)
#Schreiben
f.write(_mapped)
else:
#Leere Datei erstellen
f.write([])
def write_all_or_error(rows, filter_key, filter_value, write_key):
#Machen Sie mehrere kv
kvs = as_kvs(rows)
#Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
_filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
if _filtered:
#Extrahieren Sie alle Zeilen mit dem angegebenen Schlüssel
_mapped = map(lambda row: row[write_key], _filtered)
#Schreiben
f.write(_mapped)
else:
#Error
raise Exception("no result")
main.py
# status,Gegeben eine CSV bestehend aus Code
#Nach Code sortieren
#Der erste Fall, in dem der Status aktiv ist
#Schreiben Sie den Code aus
#Wenn nicht, erstellen Sie einfach eine Datei
csv.write_first_one_or_empty(
[['status', 'code'], ['dead', '001'], ['active', '003'], ['active', '002']],
'code', 'status', 'active', 'code'
)
#Ergebnis
# write: ['002']
main.py
# name,Gegeben eine CSV bestehend aus Geschlecht
#Alle Fälle, in denen das Geschlecht männlich ist
#Schreibe den Namen auf
#Wenn nicht, erstellen Sie einfach eine Datei
csv.write_all_or_empty(
[['name', 'gender'], ['Eva', 'female'], ['Sunny', 'female']],
'gender', 'male', 'name'
)
#Ergebnis
# write: []
main.py
# status,Geben Sie csv bestehend aus tel
#Alle Fälle, in denen der Status tot ist
#Export tel
#Sonst ein Fehler
csv.write_all_or_error(
[['status', 'tel'], ['dead', '090-1111-1111'], ['active', '090-9999-9999']],
'status', 'dead', 'tel'
)
#Ergebnis
# write: ['090-1111-1111']
def write_first_one_or_empty(rows, sort_key, filter_key, filter_value, write_key):
- #Machen Sie mehrere kv
+ # as kvs
kvs = as_kvs(rows)
- #Nach angegebenem Schlüssel sortieren
+ # sort by specified key
_sorted = sorted(kvs, key=lambda row: row[sort_key])
- #Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
+ # filter by specified key and value
_filtered = filter(lambda row: row[filter_key] == filter_value, _sorted)
if 0 < len(_filtered):
- #Extrahieren Sie die erste Zeile mit dem angegebenen Schlüssel
+ # extract by specified key and first one
_mapped_one = map(lambda row: row[write_key], _filtered)[0]
- #Schreiben
+ # write
f.write([_mapped_one])
else:
- #Leere Datei erstellen
+ # write empty
f.write([])
def write_all_or_empty(rows, filter_key, filter_value, write_key):
- #Machen Sie mehrere kv
+ # as kvs
kvs = as_kvs(rows)
- #Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
+ # filter by specified key and value
_filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
if _filtered:
- #Extrahieren Sie alle Zeilen mit dem angegebenen Schlüssel
+ # extract by specified key
_mapped = map(lambda row: row[write_key], _filtered)
- #Schreiben
+ # write
f.write(_mapped)
else:
- #Leere Datei erstellen
+ # write empty
f.write([])
def write_all_or_error(rows, filter_key, filter_value, write_key):
- #Machen Sie mehrere kv
+ # as kvs
kvs = as_kvs(rows)
- #Filtert nur, wenn der angegebene Schlüssel den angegebenen Wert hat
+ # filter by specified key and value
_filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
if _filtered:
- #Extrahieren Sie alle Zeilen mit dem angegebenen Schlüssel
+ # extract by specified key
_mapped = map(lambda row: row[write_key], _filtered)
- #Schreiben
+ # write
f.write(_mapped)
else:
- #Error
+ # error
raise Exception("no result")
Die Methode, die ausgeschnitten wurde, ist wie folgt
+def sort_by_specified_key(kvs, key):
+ return sorted(kvs, key=lambda row: row[key])
+def filter_by_specified_key_and_value(kvs, key, value):
+ return filter(lambda row: row[key] == value, kvs)
+def extract_by_specified_key_and_first_one(kvs, key):
+ return kvs[0][key]
+def extract_by_specified_key(kvs, key):
+ return map(lambda row: row[key], kvs)
+def error():
+ raise Exception("no result")
Der Hauptkörper ist so
-def write_first_one_or_empty(rows, sort_key, filter_key, filter_value, write_key):
+def write_first_one_or_empty(rows, sort_key, filter_key, filter_value, extraction_key):
- # as kvs
kvs = as_kvs(rows)
- # sort by specified key
- _sorted = sorted(kvs, key=lambda row: row[sort_key])
+ _sorted = sort_by_specified_key(kvs, sort_key)
- # filter by specified key and value
- _filtered = filter(lambda row: row[filter_key] == filter_value, _sorted)
+ _filtered = filter_by_specified_key_and_value(_sorted, filter_key, filter_value)
if 0 < len(_filtered):
- # extract by specified key and first one
- _mapped_one = map(lambda row: row[write_key], _filtered)[0]
- # write
- f.write([_mapped_one])
+ extracted_one = extract_by_specified_key_and_first_one(_filtered, extraction_key)
+ f.write([extracted_one])
else:
- # write empty
f.write([])
-def write_all_or_empty(rows, filter_key, filter_value, write_key):
+def write_all_or_empty(rows, filter_key, filter_value, extraction_key):
- # as kvs
kvs = as_kvs(rows)
- # filter by specified key and value
- _filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
+ _filtered = filter_by_specified_key_and_value(kvs, filter_key, filter_value)
if _filtered:
- # extract by specified key
- _mapped = map(lambda row: row[write_key], _filtered)
- # write
- f.write(_mapped)
+ extracted = extract_by_specified_key(_filtered, extraction_key)
+ f.write(extracted)
else:
- # write empty
f.write([])
-def write_all_or_error(rows, filter_key, filter_value, write_key):
+def write_all_or_error(rows, filter_key, filter_value, extraction_key):
- # as kvs
kvs = as_kvs(rows)
- # filter by specified key and value
- _filtered = filter(lambda row: row[filter_key] == filter_value, kvs)
+ _filtered = filter_by_specified_key_and_value(kvs, filter_key, filter_value)
if _filtered:
- # extract by specified key
- _mapped = map(lambda row: row[write_key], _filtered)
- # write
- f.write(_mapped)
+ extracted = extract_by_specified_key(_filtered, extraction_key)
+ f.write(extracted)
else:
- # error
- raise Exception("no result")
+ error()
Ich habe "Kopf" und "Schwanz" vorbereitet, weil der Indexzugriff etwas unfreundlich ist.
+def head(xs):
+ return xs[0]
+def tail(xs):
+ return xs[1:]
Wo zu verwenden
def as_kvs(rows):
- keys = rows[0]
- value_rows = rows[1:]
+ keys = head(rows)
+ value_rows = tail(rows)
def extract_by_specified_key_and_first_one(kvs, key):
- return kvs[0][key]
+ return head(kvs)[key]
"Filter_by_specified_key_and_value" wurde geändert, um "Prädikat" anstelle von "Schlüssel, Wert" zu erhalten, um etwas flexibler zu sein
-def filter_by_specified_key_and_value(kvs, key, value):
- return filter(lambda row: row[key] == value, kvs)
+def filter_by_predicate(kvs, predicate):
+ return filter(predicate, kvs)
Dann macht filter_by_predicate
nichts weiter als filter
und verwirft es.
-def filter_by_predicate(kvs, predicate):
- return filter(predicate, kvs)
Dann habe ich "Kopf" gemacht, damit ich "Extrakt_von_spezifiziertem_Schlüssel_und_Ersten_Ein" nicht vorbereiten muss. Wenn die Namen der in kleine Teile unterteilten Methoden korrekt sind, ist es schwierig, dass die Verarbeitung unklar wird, selbst wenn sie in Kombination verwendet werden.
-def extract_by_specified_key_and_first_one(kvs, key):
- return head(kvs)[key]
Hier ist der Hauptteil, der das Obige widerspiegelt
-def write_first_one_or_empty(rows, sort_key, filter_key, filter_value, extraction_key):
+def write_first_one_or_empty(rows, sort_key, predicate, extraction_key):
kvs = as_kvs(rows)
_sorted = sort_by_specified_key(kvs, sort_key)
- _filtered = filter_by_specified_key_and_value(_sorted, filter_key, filter_value)
+ _filtered = filter(predicate, _sorted)
if 0 < len(_filtered):
- extracted_one = extract_by_specified_key_and_first_one(_filtered, extraction_key)
+ extracted_one = head(_filtered)[extraction_key]
f.write([extracted_one])
else:
f.write([])
-def write_all_or_empty(rows, filter_key, filter_value, extraction_key):
+def write_all_or_empty(rows, predicate, extraction_key):
kvs = as_kvs(rows)
- _filtered = filter_by_specified_key_and_value(kvs, filter_key, filter_value)
+ _filtered = filter(predicate, kvs)
if _filtered:
extracted = extract_by_specified_key(_filtered, extraction_key)
f.write(extracted)
else:
f.write([])
-def write_all_or_error(rows, filter_key, filter_value, extraction_key):
+def write_all_or_error(rows, predicate, extraction_key):
kvs = as_kvs(rows)
- _filtered = filter_by_specified_key_and_value(kvs, filter_key, filter_value)
+ _filtered = filter(predicate, kvs)
if _filtered:
extracted = extract_by_specified_key(_filtered, extraction_key)
f.write(extracted)
else:
error()
filter
bis f.write
in den unteren beiden der drei Hauptkörpermethoden ist genau der gleiche, also schneiden Sie ihn aus.+def filter_and_extract_and_write_if_not_empty(kvs, predicate, extraction_key):
+ _filtered = filter(predicate, kvs)
+
+ if _filtered:
+ extracted = extract_by_specified_key(_filtered, extraction_key)
+ f.write(extracted)
Da es ausgeschnitten wurde, nahm die Anzahl der Linien im Hauptkörper ab
def write_all_or_empty(rows, predicate, extraction_key):
kvs = as_kvs(rows)
- _filtered = filter(predicate, kvs)
+ filter_and_extract_and_write_if_not_empty(kvs, predicate, extraction_key)
- if _filtered:
- extracted = extract_by_specified_key(_filtered, extraction_key)
- f.write(extracted)
- else:
+ if not kvs:
f.write([])
def write_all_or_error(rows, predicate, extraction_key):
kvs = as_kvs(rows)
- _filtered = filter(predicate, kvs)
+ filter_and_extract_and_write_if_not_empty(kvs, predicate, extraction_key)
- if _filtered:
- extracted = extract_by_specified_key(_filtered, extraction_key)
- f.write(extracted)
- else:
+ if not kvs:
error()
filter_and_extract_and_write_if_not_empty
umzuleitenund
werden verwendetund
haben, werden sie es oft für Sie tunDie oben erwähnte schlechte Politik wird gekürzt und überarbeitet
Achten Sie auf die zweite Körpermethode
Diesmal muss die Verarbeitung für den Fall nicht explizit durch den Inhalt der Liste und den Fall für die leere Liste getrennt werden. Wenn die Verarbeitung, an die die Liste übergeben wird, dieselbe ist, muss die Länge der Liste nicht bekannt sein (sollte es nicht sein).
Es ist besser, dies an "f.write" zu übergeben, ohne zu wissen, ob es sich um einen Inhalt oder eine leere Liste handelt
def write_all_or_empty(rows, predicate, extraction_key):
kvs = as_kvs(rows)
_filtered = filter(predicate, kvs)
- if _filtered:
- extracted = extract_by_specified_key(_filtered, extraction_key)
- f.write(extracted)
- else:
- f.write([])
+ extracted = extract_by_specified_key(_filtered, extraction_key)
+ f.write(extracted)
Achten Sie als nächstes auf die erste Körpermethode.
Wenn dies keine leere Liste ist, wird das erste Element herausgenommen, verarbeitet und erneut aufgelistet.
Dies
Der Fluss
map
Ich werde die Idee in den Fluss ändern
Bereiten Sie zunächst eine Methode vor, um das passende erste Element mit einer maximalen Länge von 1 aus der Liste zu erhalten.
+def find_first(kvs, predicate):
+ for kv in kvs:
+ if predicate(kv):
+ return [kv]
+ else:
+ return []
Dann müssen Sie sich nicht um den Inhalt wie den zweiten der Hauptkörpermethode kümmern. Da es sich um eine Listenkonvertierung handelt, können Sie außerdem "extract_by_specified_key" anstelle von "head" und "key" verwenden.
def write_first_one_or_empty(rows, sort_key, predicate, extraction_key):
kvs = as_kvs(rows)
_sorted = sort_by_specified_key(kvs, sort_key)
+ first = find_first(_sorted, predicate)
- _filtered = filter(predicate, _sorted)
-
- if 0 < len(_filtered):
- extracted_one = head(extract_by_specified_key(_filtered, extraction_key))
- f.write([extracted_one])
- else:
- f.write([])
+ extracted = extract_by_specified_key(first, extraction_key)
+ f.write(extracted)
Sowohl die "if" -Klausel als auch die "else" -Klausel der Hauptteilmethoden 1 und 2 passen in die Granularität der "Exportverarbeitung ohne Kenntnis der Listenlänge". In einem schlechten Beispiel waren "if" und "else" eine Gruppe von Exportprozessen, aber es war eine schlechte Idee, nur "if" auszuschneiden.
list.py
war in Ordnung, aber der Name widerspricht der Standard list ()
, also habe ich ihn entsprechend verschoben)l.py
+# -*- coding: utf-8 -*-
+
+
+def head(xs):
+ return xs[0]
+
+
+def tail(xs):
+ return xs[1:]
+
+
+def find_first(xs, predicate):
+ for x in xs:
+ if predicate(x):
+ return [x]
+ else:
+ return []
kvs
zum Sortieren und Extrahieren verwenden, was nur eine Wörterbuchoperation ist. Erstellen Sie also d.py
und entfernen Sie es aus csv.py
.d.py
+# -*- coding: utf-8 -*-
+
+
+def extract_by_specified_key(xs, key):
+ return map(lambda x: x[key], xs)
+
+
+def sort_by_specified_key(xs, key):
+ return sorted(xs, key=lambda x: x[key])
-def as_kvs(rows):
+def __as_kvs(rows):
-def error():
+def __error():
kvs
ist nur eine temporäre Datenstruktur, die durch Konvertieren der von csv.py
erwarteten Datenstruktur erstellt wird, um die interne Verarbeitung zu vereinfachen.
kvs
ist eigentlich dict
, aber der Typ dict
erscheint nicht in den veröffentlichten Argumenten oder im Rückgabewert von csv.py
.
Mit anderen Worten, es gibt keinen "dict" -Typ als Funktion, die vom Modul bereitgestellt wird, daher sollte er nicht verfügbar gemacht werden.
Darüber hinaus ist der Argumenttyp von "as_kvs" "list", es gibt jedoch Einschränkungen wie "header + [body]" -Konfiguration und dass alle Spalten übereinstimmen, also "l.py" und " Ich dachte, dass es vorzuziehen ist, "csv.py" privat zu verarbeiten, anstatt "d.py"
Bei etwas größeren Modulen kann es äußerst schwierig sein zu wissen, wo und wie viele "private" Module verwendet werden.
Wenn Sie dies tun, kann es schwierig sein, die "private" Methode umzugestalten oder den Einflussbereich zu verstehen, was sehr schwierig sein kann.
public 1 -> private 1 -> private 2 -> private 3
public a -> private a -> private b
public x -> private x
Es ist viel einfacher, das ganze Bild zu erfassen, wenn Sie glauben, dass es tatsächlich drei "öffentliche" gibt. Sie können "privat" beruhigt umgestalten.
public 1 -> private 1
|
V
public a -> private a -> private b
^
|
public x -> private x -> private y
private 1
und private x
können bis zu einem gewissen Grad leicht geändert werden. Wenn Sie jedoch private b
leicht korrigieren, wirkt sich dies auf alle public
aus.
Versuchen Sie, "privat" in der Methode zu definieren, die nur von einer Stelle aus verwendet wird
Dies ist die Methode, die ich ohne Erlaubnis ausprobiert habe, als ich dort war, aber es gibt keine richtige Ausstellung oder Diskussion, aber ich denke, dass es ein guter Schachzug ist und ich benutze sie häufig in Einwegschnüren und Soloprojekten
Da "__error" nur an einer Stelle verwendet wird, habe ich es mit "def" in "def" vorbereitet
Übrigens habe ich auch das nervige "__" gelöscht, weil es von außen sowieso unsichtbar wurde.
def write_all_or_error(rows, predicate, extraction_key):
+ def write_or_error(kvs):
+ if kvs:
+ f.write(kvs)
+ else:
+ raise Exception("no result")
+
kvs = __as_kvs(rows)
_filtered = filter(predicate, kvs)
extracted = d.extract_by_specified_key(_filtered, extraction_key)
- if extracted:
- f.write(extracted)
- else:
- __error()
+ write_or_error(extracted)
Natürlich wird __as_kvs
von vielen Orten aus verwendet, also ändern Sie es nicht.
Die Verantwortung des Moduls beschränkt sich also auf "Konvertierung" und der Test wird implementiert.
Es wird beschlossen, mit "return" ohne "output" zu enden. Gleichzeitig wurde der Methodenname von "write_" in "extract_" geändert.
-def write_first_one_or_empty(rows, sort_key, predicate, extraction_key):
+def extract_first_one_or_empty(rows, sort_key, predicate, extraction_key):
kvs = __as_kvs(rows)
_sorted = d.sort_by_specified_key(kvs, sort_key)
first = l.find_first(_sorted, predicate)
- extracted = d.extract_by_specified_key(first, extraction_key)
- f.write(extracted)
+ return d.extract_by_specified_key(first, extraction_key)
-def write_all_or_empty(rows, predicate, extraction_key):
+def extract_all_or_empty(rows, predicate, extraction_key):
kvs = __as_kvs(rows)
_filtered = filter(predicate, kvs)
- extracted = d.extract_by_specified_key(_filtered, extraction_key)
- f.write(extracted)
+ return d.extract_by_specified_key(_filtered, extraction_key)
-def write_all_or_error(rows, predicate, extraction_key):
- def write_or_error(kvs):
- if kvs:
- f.write(kvs)
+def extract_all_or_error(rows, predicate, extraction_key):
+ def it_or_error(xs):
+ if xs:
+ return xs
else:
raise Exception("no result")
kvs = __as_kvs(rows)
_filtered = filter(predicate, kvs)
extracted = d.extract_by_specified_key(_filtered, extraction_key)
- write_or_error(extracted)
+ return it_or_error(extracted)
Infolgedessen verschwindet "import", sodass bestätigt werden kann, dass "csv.py" file-io nicht mehr verarbeitet.
-from private import f
Der Test sieht so aus
csv_test.py
# -*- coding: utf-8 -*-
import csv
assert csv.extract_first_one_or_empty(
[['status', 'code'], ['dead', '001'], ['active', '003'], ['active', '002']],
'code', lambda kvs: kvs['status'] == 'active', 'code'
) == ['002']
assert csv.extract_first_one_or_empty(
[['status', 'code'], ['dead', '001']],
'code', lambda kvs: kvs['status'] == 'active', 'code'
) == []
csv.py
# -*- coding: utf-8 -*-
import l
import d
def __as_kvs(rows):
keys = l.head(rows)
value_rows = l.tail(rows)
return [dict(zip(keys, value_row)) for value_row in value_rows]
def extract_first_one_or_empty(rows, sort_key, predicate, extraction_key):
kvs = __as_kvs(rows)
_sorted = d.sort_by_specified_key(kvs, sort_key)
first = l.find_first(_sorted, predicate)
return d.extract_by_specified_key(first, extraction_key)
def extract_all_or_empty(rows, predicate, extraction_key):
kvs = __as_kvs(rows)
_filtered = filter(predicate, kvs)
return d.extract_by_specified_key(_filtered, extraction_key)
def extract_all_or_error(rows, predicate, extraction_key):
def it_or_error(xs):
if xs:
return xs
else:
raise Exception("no result")
kvs = __as_kvs(rows)
_filtered = filter(predicate, kvs)
extracted = d.extract_by_specified_key(_filtered, extraction_key)
return it_or_error(extracted)
def
gibt, überspringen Sie es und lesen Sie vom Anfang des Textes)l.py
und d.py
, die in Zukunft nützlich zu sein scheinen, wurden geborenIch kann es nicht auf den Punkt bringen ...
# Dieser Prozess ist für ~ ~ Spezifikationen
usw.# ~ ~ wurde berücksichtigt und so implementiert
usw.und
enthältlen ()
oder head ()
oder .split ()
head ()
einzeln zu lesenfilter
auf find_first
gesetzt ist und wo es bis zum Ende filter
warIf
Teil von wenn sonst leer schreiben
und wenn sonst Fehler schreiben
def
in def
Scala kann gehorsam sein
def upperJoin(xs: List[String], sep: String): String = {
def upper(xs: List[String]): List[String] = xs.map(_.toUpperCase)
def join(xs: List[String]): String = xs.mkString(sep)
join(upper(xs))
}
upperJoin(List("hello", "world"), " ") // HELLO WORLD
Auch mit Java ist es möglich, Function <T, R>
etc. zu verwenden.
public static String upperJoin(List<String> xs, String sep) {
Function<List<String>, List<String>> upper = _xs -> _xs.stream().map(String::toUpperCase).collect(toList());
Function<List<String>, String> join = _xs -> _xs.stream().collect(joining(sep));
return join.apply(upper.apply(xs));
}
upperJoin(asList("hello", "world"), " "); // HELLO WORLD
haskell kann auch sein Oder besser gesagt, die Idee kommt aus dem Sinn, eine Haskell-Funktion nach Wert zu definieren.
upperJoin xs sep = (join . upper) xs
where
upper = map (map toUpper)
join = intercalate sep
upperJoin ["hello", "world"] " " -- HELLO WORLD
Das Java-Beispiel befindet sich also in der Nähe von Haskell, und Sie können es wie folgt in Python schreiben: (In PEP 8 verstößt es gegen den Kodierungsstandard, "Lambda" zu benennen und zu binden, aber ich hasse es zu nisten, daher gibt es hier viele Leute, wenn ich alleine bin.)
def upper_join(xs, sep):
upper = lambda xs: [x.upper() for x in xs]
join = lambda xs: sep.join(xs)
return join(upper(xs))
upper_join(['hello', 'world'], ' ') # HELLO WORLD
kvs
war Liste
von dict
, also war es etwas anders, es einfach in d.py
zu setzen ...Ich wollte es nur versuchen, also war ich zufrieden
Es spielt keine Rolle, aber wenn ich die schwarzen Buchstaben auf den roten und grünen Bereichen sehe, denke ich immer, dass es wie eine Wassermelone aussieht.
Recommended Posts