IP adressen sortieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
xerxes_

IP adressen sortieren

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 09:18

hi,
in einer datei sind ip adresse aufgelistet. die IPs sind nicht geordnet, sprich die IPs liegen kreuz und quer herum. nun ist es meine aufgabe diese zu sortieren. ich hab den inhalt der datei in eine liste gepackt und wollte munter mit list.sort() die sache sortieren lassen. hat auch gut funktioniert nur wisst ihr bestimmt schon wie das resultat aussieht.
192.168.0.0
192.168.0.1
192.168.0.10
192.168.0.11
...

nun meine frage an euch wie würdet ihr dieses problem lösen?
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Re: IP adressen sortieren

Beitragvon joerg » Dienstag 22. Juni 2004, 10:46

xerxes_ hat geschrieben:nun meine frage an euch wie würdet ihr dieses problem lösen?


Code: Alles auswählen

ips = ['192.168.0.0', '192.168.0.1', '192.168.0.10', '192.168.0.11']
tmp = [([int(i) for i in ip.split('.')], ip) for ip in ips]
tmp.sort()
ipsorted = [b for a,b in tmp]


Da wird eine Liste gebastelt, deren Elemente Tupel aus den aufbereiteten IPs und den String-IPs sind, dann sortiert, und schließlich wieder die originalen String-IPs rausgesucht.

"Aufbereitung" ist in dem Fall eine Umwandlung des IP-Strings in eine Liste von Zahlen, weil die nämlich besser sortierbar ist.

Alternativ kannst Du zwischenzeitlich auch die Original-Strings vergessen (also aus 'tmp' draußenlassen) und nach dem Sortieren die String-IPs wieder aus den Zahlen zusammenbasteln, das kann übersichtlicher aussehen, aber wird wahrscheinlich nicht schneller sein:

Code: Alles auswählen

tmp = [[int(i) for i in ip.split('.')] for ip in ips]
tmp.sort()
ipsorted = ['%d.%d.%d.%d' % tuple(i) for i in tmp]


Jörg
"Sie sind nicht berechtigt, unrechtmäßige Kopien dieses Datenträgers zu erstellen." - Microsoft-Weisheit auf einer CD von MS-VisualC++-6.0
Gast

Beitragvon Gast » Dienstag 22. Juni 2004, 12:16

Code: Alles auswählen

ips.sort(lambda x,y: cmp(int(x.split(".")[-1]),int(y.split(".")[-1])


@joerg viel zu kompliziert ;)
Gast

Beitragvon Gast » Dienstag 22. Juni 2004, 12:17

Code: Alles auswählen

ips.sort(lambda x,y: cmp(int(x.split(".")[-1]),int(y.split(".")[-1])))

sorry da fehlten klammern
Gast

Beitragvon Gast » Dienstag 22. Juni 2004, 12:30

Bei allen stellen:

Code: Alles auswählen

ips.sort(lambda x,y: cmp([int(i) for i in x.split(".")],[int(i) for i in y.split(".")]))
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Beitragvon joerg » Dienstag 22. Juni 2004, 12:46

Hallo "Gast",
daß man dem sort() eine Vergleichsfunktion schon mitgeben kann, war mir schon bewußt.

Nur ging ich irgendwie davon aus, daß die Liste recht lang ist. Und performancemäßig wird Deine Lösung eher schlecht aussehen. Das wurde IMO auch hier im Forum schon mal diskutiert.

Falls die Geschwindigkeit egal ist, hat so ein Einzeiler natürlich auch einen gewissen Charme. ;-)

Jörg
"Sie sind nicht berechtigt, unrechtmäßige Kopien dieses Datenträgers zu erstellen." - Microsoft-Weisheit auf einer CD von MS-VisualC++-6.0
xerxes_

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 13:24

hi,
eure beispiele funktionieren gut. nun ein weiteres problem:
der inhalt der datei ist folgendermaßen aufgebaut:

192.168.0.21 <aufgelöster hostname> <aufgelöste ipadresse durch hostname>

nun möchte ich gerne die ganze zeile verschieben, jedoch das kriterium bleibt immer die ipadresse. das problem ist, bin nicht so bewandert in der python syntax und im "thinking in python" deshalb suche ich um rat bzw um lösungen.
danke im vorraus
gruß xerxes_
Gast

Beitragvon Gast » Dienstag 22. Juni 2004, 13:38

xerxes_ hat geschrieben: ... das problem ist, bin nicht so bewandert in der python syntax und im "thinking in python" deshalb suche ich um rat bzw um lösungen.


Wenn ein ip.split('.') einen String an den Punkten auftrennt, wie kann man die Zeile dann wohl an Leerzeichen auftrennen, um nur den ersten Teil weiterzuverarbeiten? ;-)

Ersetze mal einen Ausdruck in meinem ersten Vorschlag durch

ip.split(' ')[0].split('.')

Wenn es klappt, war es die richtige Stelle! Wenn nicht, suche weiter! ;-)

Jörg
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Beitragvon joerg » Dienstag 22. Juni 2004, 13:43

Ooops, jetzt isses mir auch passiert, das Einlogenvergessen. Der da oben war von mir!

Jörg
"Sie sind nicht berechtigt, unrechtmäßige Kopien dieses Datenträgers zu erstellen." - Microsoft-Weisheit auf einer CD von MS-VisualC++-6.0
xerxes_

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 13:43

hi,
ich hab vielleicht eine schnelle für mich lösbare lösung erarbeitet :)
und zwar folgendermaßen:

in der datei stehen die ergebnisse einer bestimmten range die aufgelöst wurde zb. 192.168.0.0/19

nun kann ich dem python script die range ja als commandozeilen parameter übergeben -> errechnet die rang -> durchläuft die range -> sucht nach jeder ip in der datei -> findet er was -> nimmt er sich die zeile und schreibt sie einen neue datei... :), schlussendlich kann ich noch einige kosmetische änderung an der datei einfügen zb nach bestimmten bestimmten anzahl von zeilen "seite1" ... "seite2" hinschreiben...
gruß xerxes_
Gast

Beitragvon Gast » Dienstag 22. Juni 2004, 14:25

frage scheint geklärt... aber egal

Code: Alles auswählen

ips.sort(lambda x,y,z={}: cmp(x in z and z[x] or z.__setitem__(x,[int(i) for i in x.split(".")]) or z[x],y in z and z[y] or z.__setitem__(y,[int(i) for i in y.split(".")]) or z[y]))


dies ist schneller ;) aber etz wirds komplizierter ^^
hab grad nen test gemacht deins ist trotzdem schneller um ca 30% als das...
xerxes_

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 14:33

Code: Alles auswählen

import string

source = open("C:\\_dns.log", "r")
dns_list = source.readlines()
source.close()

split_list = []

start1 = 213
start2 = 147
start3 = 0
start4 = 0

ende1 = 213
ende2 = 147
ende3 = 0
ende4 = 255

target = open("C:\\newdns.log", "w")

for j in range(int(start1), int(ende1) + 1):
    for k in range(int(start2), int(ende2) + 1):
        for l in range(int(start3), int(ende3) + 1):
            for h in range(int(start4), int(ende4) + 1):
               
                current_ip = str(j) + "." + str(k) + "." + str(l) + "." + str(h)
               
                for i in dns_list:
                    split_list(string.split(i, " "))
                   
                    try:
                        if(split_list[2] != ''):
                            ip = split_list[2]
                            if(current_ip == ip):
                                target.write(i)
                                break
                               
                        else:
                            ip = split_list[3]
                            if(current_ip == ip):
                                target.write(i)
                                break
                           
                    except:
                        print ''

target.close()




Code: Alles auswählen

>>>
Traceback (most recent call last):
  File "C:\Python23\Lib\site-packages\Pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Dokumente und Einstellungen\mz\Desktop\python scripte\sort_advanced.py", line 32, in ?
TypeError: 'list' object is not callable
>>>


kannste mir helfen jörg?
gruß xerxes_
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 22. Juni 2004, 14:44

Hi xerxes_,

das is wohl etwas daneben:

Code: Alles auswählen

...
split_list(string.split(i, " "))
...

Und 5 verschachtelte Forschleifen ???


Gruß

Dookie
xerxes_

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 15:18

hi
4 verschachtelte schleifen brauch ich um die range hochzuzählen...

die andere um die liste durchzugehen
xerxes_

Beitragvon xerxes_ » Dienstag 22. Juni 2004, 15:20

hier der nächste fehler

Code: Alles auswählen

>>>
Traceback (most recent call last):
  File "C:\Python23\Lib\site-packages\Pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "C:\Dokumente und Einstellungen\mz\Desktop\python scripte\sort_advanced.py", line 29, in ?
    current_ip = str(j) + "." + str(k) + "." + str(l) + "." + str(h)
TypeError: 'str' object is not callable
>>>


wie kann ich denn eine integer variable in string umwandeln?

Wer ist online?

Mitglieder in diesem Forum: hansjürgen