Knock 100-Sprachverarbeitung, veröffentlicht auf der Webseite des Inui-Okazaki-Labors der Tohoku-Universität zum Training der Verarbeitung natürlicher Sprache und von Python. Ich werde nlp100 /) herausfordern. Ich habe vor, den darin implementierten Code und die Techniken, die unterdrückt werden sollten, zu notieren. Der Code wird auch auf GitHub veröffentlicht.
Nur hier denke ich, wäre es gut, eine kleine Erklärung der UNIX-Befehle sowie von Python einzufügen.
Detaillierte Optionen für UNIX-Befehle finden Sie im Befehl man
oder auf der ITpro-Website. Sie werden es richtig lernen!
hightemp.txt ist eine Datei, in der die Aufzeichnung der höchsten Temperatur in Japan im tabulatorgetrennten Format "Präfektur", "Punkt", "℃" und "Tag" gespeichert wird. Erstellen Sie ein Programm, das die folgende Verarbeitung ausführt, und führen Sie hightemp.txt als Eingabedatei aus. Führen Sie außerdem denselben Prozess mit einem UNIX-Befehl aus und überprüfen Sie das Ausführungsergebnis des Programms.
Empfangen Sie die natürliche Zahl N mithilfe von Befehlszeilenargumenten und teilen Sie die Eingabedatei zeilenweise in N. Erzielen Sie die gleiche Verarbeitung mit dem Befehl split.
16.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 16.py
import sys
def split_file(filename, number_of_parts):
with open(filename) as f:
lines = f.readlines()
if len(lines) % number_of_parts != 0:
raise Exception("Undividable by N=%d" % number_of_parts)
else:
number_of_lines = len(lines) / number_of_parts
for i in range(number_of_parts):
with open("split%s.txt" % str(i), "w") as w:
w.writelines(lines[number_of_lines * i: number_of_lines * (i + 1)])
if __name__ == '__main__':
try:
split_file(sys.argv[1], int(sys.argv[2]))
except Exception as err:
print("Error:", err)
Der schwierige Teil beim Aufteilen in N ist, wenn die ursprüngliche Anzahl von Zeilen nicht durch N teilbar ist. Ich denke, es gibt verschiedene Dinge zu tun, wenn es nicht teilbar ist, aber dieses Mal werde ich versuchen, den Fehler zu erhöhen.
Für die normale Ausnahmebehandlung
try:
#Verarbeitung, die wahrscheinlich einen Fehler verursacht
# ex) a = 10/0 (Nullteilung, ZeroDivisionError)
except [Fehlername]:
#Was tun, wenn ein Fehler auftritt?
# ex) print("Unable to divide by 0")Und
# except [Ein Fehler] as err:Wenn Sie schreiben, wird der Fehlerinhalt in e gespeichert
finally:
#Verarbeitung, die unabhängig vom Auftreten eines Fehlers durchgeführt werden muss
Es kann in Form von beschrieben werden. Dies funktioniert auch dann, wenn Sie den im Ausnahmeteil festgestellten Fehlertyp nicht angeben. Es wird jedoch empfohlen, ihn so weit wie möglich anzugeben. Dies liegt daran, dass es zu einer Brutstätte von Fehlern wird, da es jeden Fehler aufnimmt und den Betrieb (gewaltsam) ermöglicht.
Außerdem mache ich diesmal "Raise" alleine. Wenn ich etwas mehr versuche, kann ich meine eigenen Ausnahmen implementieren, aber ich verstehe Python Class immer noch nicht. Deshalb habe ich mich dieses Mal entschieden, die vorhandene "Ausnahme" zu verwenden.
Um "Fehler" zu generieren, schreiben Sie "Ausnahme auslösen" ("Fehlermeldung"). Dann wird an dieser Stelle zwangsweise ein "Fehler" erzeugt. Dieses Mal wird ein Fehler generiert, wenn die Anzahl der Zeilen in der Datei nicht durch die natürliche Zahl "N" teilbar ist.
if name == 'main':
Ich sah auch zuerst die Beschreibung "if name ==" __ main __ ":" und es wurde "?". Wenn Sie dieses Programm direkt aufrufen, wird diese if-Anweisung ausgeführt. Wenn Sie es umgekehrt indirekt von einem anderen Programm durch "Import" usw. aufrufen, wird das Innere der "if" -Anweisung nicht ausgeführt. In dem Artikel in Qiita wurde diese Beschreibung grundsätzlich weggelassen, aber aufgrund der Ausnahmebehandlung wird sie diesmal zusammen beschrieben.
//Wenn in drei geteilt, 24 ÷ 3=Alle 8 Zeilen wird eine Datei generiert
$ split -l 8 hightemp.txt
$ ls
xaa xab xac hightemp.txt
$ cat xaa
Präfektur Kochi Egawasaki 41 2013-08-12
(Weggelassen...)
40 Katsunuma, Präfektur Yamanashi.5 2013-08-10
$ cat xab
40 Koshiya, Präfektur Saitama.4 2007-08-16
(Weggelassen...)
40 Sakata, Präfektur Yamagata.1 1978-08-03
$ cat xac
Mino 40, Präfektur Gifu 2007-08-16
(Weggelassen...)
Präfektur Aichi Nagoya 39.9 1942-08-02
Ursprünglich gibt split
die Anzahl der zu teilenden Zeilen an, so dass es schwierig erscheint, N split direkt anzugeben. Ich konnte mir keine Technik zum Teilen in der Befehlszeile vorstellen, also beschloss ich, die eingegebene Person zu bitten, "24 ÷ N" zu berechnen und die Option anzugeben.
Suchen Sie den Typ der Zeichenfolge in der ersten Spalte (eine Reihe verschiedener Zeichenfolgen). Verwenden Sie zur Bestätigung die Befehle sort und uniq.
17.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 17.py
import sys
filename = sys.argv[1]
prefectures = set()
with open(filename) as f:
line = f.readline()
while line:
prefectures.add(line.split()[0])
line = f.readline()
for pref in prefectures:
print(pref)
set
ist ein Set, das keine Vervielfältigung zulässt, daher ist es diesmal perfekt.
$ cut -f 1 hightemp.txt | sort | uniq
Präfektur Chiba
Saitama
Präfektur Osaka
(Weggelassen...)
Präfektur Shizuoka
Präfektur Kochi
Präfektur Wakayama
Sie sagten, Sie hätten "sort" und "uniq" verwendet, aber ich habe auch "cut" verwendet, weil es ein Hindernis war. Intuitiv scheint es, dass nur "uniq" dies kann, aber "uniq" funktioniert unter der Annahme, dass es sortiert ist, so dass "sort" unverzichtbar ist.
Ordnen Sie jede Zeile in umgekehrter Reihenfolge der Zahlen in der dritten Spalte an (Hinweis: Ordnen Sie den Inhalt jeder Zeile neu an, ohne ihn zu ändern). Verwenden Sie den Befehl sort zur Bestätigung (dieses Problem muss nicht mit dem Ergebnis der Ausführung des Befehls übereinstimmen).
18.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 18.py
import sys
with open(sys.argv[1]) as f:
lines = f.readlines()
for line in sorted(lines, key=lambda x: x.split()[2], reverse=True):
print line,
Die Sortieranzeige in der letzten "for" -Anweisung wurde zuvor in Kapitel 1 behandelt. Zu dieser Zeit habe ich es ohne Erklärung verwendet, aber dieses Mal werde ich es hier erklären.
Lambda
Es ist einfach, eine bestimmte Zeichenfolge zu sortieren, aber dieses Mal müssen wir nach der Zahl sortieren, die in der Mitte der Zeichenfolge vorhanden ist. Daher werden die Sortierkriterien mit der anonymen Funktion "Lambda" festgelegt. Es scheint schwierig zu sein, eine anonyme Funktion oder "Lambda" zu hören, aber es ist fast dasselbe wie die Funktionen, die bisher erschienen sind, außer dass sie in einer Zeile zusammengefasst sind.
#Berechnen Sie 3 mal 2
#Funktionsdefinition von def
def double(x):
return x * 3
print double(2) # 6
#Funktionsdefinition durch Lambda
double = lambda x: x * 3
print double(2) #6
In dieser Implementierung wird die Funktion, die die dritte Spalte der als Argument empfangenen Zeichenfolge zurückgibt, durch "Lambda" ausgedrückt. Sie können Ad-hoc-Funktionen schnell schreiben, daher ist es sehr praktisch, wenn Sie sie gut verwenden können.
sorted()
Wie der Name schon sagt, ist es eine Funktion, die die Liste sortiert. Die als Argument empfangene Liste wird direkt anstelle des Rückgabewerts sortiert. Seien Sie also vorsichtig, wenn Sie damit umgehen.
Sie können mit aufsteigender und absteigender Reihenfolge zwischen aufsteigender und absteigender Reihenfolge wechseln.
$ sort -r -k 3 hightemp.txt
Präfektur Kochi Egawasaki 41 2013-08-12
40 Tajimi, Präfektur Gifu.9 2007-08-16
40 Kumagai, Präfektur Saitama.9 2007-08-16
(Weggelassen...)
Toyonaka 39, Osaka.9 1994-08-08
Otsuki, Yamanashi 39.9 1990-07-19
39 Tsuruoka, Präfektur Yamagata.9 1978-08-03
Präfektur Aichi Nagoya 39.9 1942-08-02
-r
gibt die absteigende Reihenfolge an und -k 3
gibt die dritte Zeile an.
Ermitteln Sie die Häufigkeit des Auftretens der ersten Spalte jeder Zeile und zeigen Sie sie in absteigender Reihenfolge an. Verwenden Sie zur Bestätigung die Befehle cut, uniq und sort.
19.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 19.py
import sys
from collections import defaultdict
filename = sys.argv[1]
prefectures = defaultdict(int)
with open(filename) as f:
line = f.readline()
while line:
prefectures[line.split()[0]] += 1
line = f.readline()
for k, v in sorted(prefectures.items(), key=lambda x: x[1], reverse=True):
print(k)
defaultdict Das Problem bei der Arbeit mit einem Wörterbuch ist, dass Sie für einen Schlüssel, der noch nicht vorhanden ist, nicht so etwas wie "dict [key] + = 1" schreiben können, da der Anfangswert nicht vorhanden ist. Es ist "defaultdict", das dieses Problem löst, und es ist möglich, Variablen in Form der Festlegung von Anfangswerten zu deklarieren. Da wir diesmal "int" angegeben haben, ist der Anfangswert 0, aber Sie können auch einen Anfangswert mit einer komplizierteren Form festlegen. Es ist sehr nützlich.
$ cut -f 1 hightemp.txt | sort | uniq -c | sort -r | cut -c 6-
Präfektur Gunma
Präfektur Yamanashi
Präfektur Yamagata
(Weggelassen...)
Präfektur Kochi
Präfektur Ehime
Präfektur Osaka
--cut -f 1
Schneiden Sie die erste Spalte aus (Name der Präfektur)
--sort
Wenn Sie nicht sortieren, funktioniert uniq
nicht richtig, also sortieren Sie
--uniq -c
Löscht Duplikate und gibt eine eindeutige Zeile mit der Anzahl der Vorkommen vor dem Löschen aus.
--sort -r
Da es sich um die "höchste Anzahl von Vorkommen" handelt, wird sie in absteigender Reihenfolge nach der Anzahl der Vorkommen sortiert.
--cut -c 6-
Da am Anfang der Ausgabeergebniszeile zusätzliche Leerzeichen und Zeichenfolgen enthalten sind, werden das 6. und die nachfolgenden Zeichen angezeigt und die Leerzeichen gelöscht.
Dies ist auch eine Kombination von Befehlen, die bereits angezeigt wurden.
Fahren Sie mit Kapitel 3 fort.
Recommended Posts