String Variablen 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.
Antworten
markus073
User
Beiträge: 5
Registriert: Sonntag 31. Mai 2009, 10:16

Liebes Forum,

ich habe bereits vergeblich versucht folgendes zu lösen:

Ich habe eine größere Anzahl (bis zu 50) String Variablen (jede Variable wurde mit dem Inhalt je einer Textdatei befüllt).
Ich möchte nun gerne wissen welche Variablen den gleichen Inhalt haben, und diese Information in eine neue Variable speichern.

Wenn z.B. var1, var30 und var 49 gleichen Inhalts sind, würde ich gerne soetwas wie

"erstes Vorkommen von Variablen die gleich sind: var1, var30, var49"
"zweites Vorkommen von Variablen die gleich sind: [...]"

ausgeben.
Eine mehr oder weniger detaillierte Skizze, als Schups in die richtige Richtung, würde mir sehr helfen.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

du könntest die liste erstmal sortieren (liste.sort()) dann stehen alle gleichen direkt nebeneinander und du bist fast fertig.

dann müssen die gleichen texte aber auch exact gleich sein. ist das der fall?

falls nein, könntest du ähnliche strings mit difflib finden.
http://www.kinderpornos.info
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dill hat geschrieben:du könntest die liste erstmal sortieren (liste.sort()) dann stehen alle gleichen direkt nebeneinander und du bist fast fertig.
Ich fürchte, das hilft hier nicht, weil es anscheinend gar nicht um eine Liste geht, sondern tatsächlich um 50 einzelne Variablen mit den Namen var1, var2, ..., var50. Da ist wohl schon vorher irgend etwas schief gelaufen ... :(
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

dann gibt es keine hoffnung, keinen ausweg, keinen sinn... :cry:
http://www.kinderpornos.info
markus073
User
Beiträge: 5
Registriert: Sonntag 31. Mai 2009, 10:16

Danke für den guten Tipp! Ja, der Inhalt ist exakt gleich.
Nun habe ich dies hier (nur als Beispiel):

Code: Alles auswählen

var1 = "inhalt"
var2 = "istanders"
var3 = "inhalt"
var4 = "inhalt"

liste=[var1, var2, var3, var4]
print liste
liste.sort()
print liste

ausgabe vor liste.sort()
inhalt, istanders, inhalt, inhalt

ausgabe nach liste.sort()
inhalt, inhalt, inhalt, istanders


Leider komme ich noch nicht drauf wie ich hieraus nun etwas wie
"erstes Vorkommen von Variablen die gleich sind: var1, var3, var4"
ausgeben kann.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Durchlaufen und dir jeweils den Index der ersten "neuen" Variable merken. Sobald du auf eine Variable stößt, deren Inhalt nicht mit der vorherigen identisch ist, mußt du diesen Index neu setzen (nachdem du zuvor vermutlich noch irgendwas mit der damit vollständigen Gruppe von inhaltsgleichen Variablen angestellt hast).
BlackJack

@markus073: Wenn Du tatsächlich 50 fortlaufend nummerierte Namen in Deinem Programm hast, solltest Du als aller erstes diese Namen beseitigen. Statt Namen mit Nummern will man in der Regel an der Stelle eine Liste verwenden, also *einen* Namen, wo die Nummern in Form von Indizes angegeben werden können. Spart viel Schreibarbeit, und man hat auch gleich eine Datenstruktur mit der man weiterarbeiten kann.

Als nächsten Schritt müsstest Du ein Dictionary anlegen, das die Texte als Schlüssel enthält und eine Liste mit Indizes an denen der jeweilige Text steht, als Werte.

Nützliche Wertzeuge dafür: Die ``for``-Anweisung, die `enumerate()`-Funktion, und die Typen `collections.defaultdict` und `list`.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Vielleicht hilft dir das:

Code: Alles auswählen

from itertools import groupby
var = ["inhalt", "istanders", "blubb", "inhalt", "inhalt", "blubb"]
index_sorted = sorted(range(len(var)), key=var.__getitem__)
print sorted(list(g) for k, g in groupby(index_sorted, key=var.__getitem__))

Code: Alles auswählen

[[0, 3, 4], [1], [2, 5]]
BlackJack

Wobei mir das für "Produktionscode" zuviel Magie ist. Auf `__foo__`-Methoden greife ich ungerne direkt zu.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Ja, da hast du wohl recht. Extra eine Funktion zu definieren finde ich aber auch hässlich und umständlich für die paar Zeilen Wegwerfcode.

Die von dir vorgeschlagene Lösung ist ohnehin verständlicher. Ich dachte zuerst, dass das Gruppieren von gleichen Element doch ein Job für groupby wäre, aber es ist leider doch komplizierter.

Abgesehen davon: Es ist schade, dass man sorted (u.ä.) zwar eine key-Funktion übergeben kann, aber nicht einfach ein iterable, das die Schlüssel liefert ("keys=var").
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wie wärs mit ``operator.itemgetter()``?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Wie meinst du das? Hast du es ausprobiert?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ah, ``itemgetter`` macht es genau andersrum als benötigt. :oops:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
markus073
User
Beiträge: 5
Registriert: Sonntag 31. Mai 2009, 10:16

Herzlichen Dank an alle für die guten Tipps. Natürlich habt Ihr Recht, dass nur ein Dictionary Sinn macht.
Ich gebe es jetzt etwa so aus, welche Textfiles den gleichen Inhalt haben:

Code: Alles auswählen

d = { "txt1": "inhaltA",
         "txt2": "inhaltB",
         "txt3": "inhaltA",
         "txt4":"inhaltA",
		 "txt5": "inhaltC",
         "txt6":"inhaltB",
		 "txt7":"inhaltA"}

pairs = sorted((value, key) for (key, value) in d.iteritems())
for value, key in pairs:
	print value, key
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Wenn deine Keys (txtN) wirklich nur nach dem Schema N=1, 2, 3, ...10000 verlaufen, brauchst du auch kein Dictionary - was du willst ist eine Liste:

Code: Alles auswählen

["a", "b", "c", "d", "e"]
Die kannst du dann per Index benutzen:

Code: Alles auswählen

liste[0], liste[5757]
Pascal
User
Beiträge: 271
Registriert: Samstag 4. April 2009, 22:18

ich hab dazu mal ein Beispiel:

es ist zwar nicht so kurz, aber es beschränkt sich auf die Grundbegriffe, was ja auch mal ganz praktisch zum Verstehen ist :idea:

Code: Alles auswählen

woerter = ['hallo', 'ich','einen', 'hab','auch','einen','einen', 'Loesungsvorschlag', 'ich' ,'hallo']
doppelte_woerter=[]

for wort in woerter:
    if not wort in doppelte_woerter and woerter.count(wort) !=1:
            doppelte_woerter.append(wort)
            print wort , 'befindet sich ' , woerter.count(wort), 'mal in der Liste'

Grüße
Pascal
BlackJack

Auch wichtig zu verstehen ist, warum man dass da auf keinen Fall ernsthaft in Betracht ziehen sollte. Das Laufzeitverhalten ist ja gruselig.
Antworten