doppelte elemente in textdatei suchen

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
taake
User
Beiträge: 124
Registriert: Donnerstag 14. Oktober 2010, 08:49

Freitag 2. November 2012, 11:19

Moin,

ich hab hier ein kleines Problem und komme einfach nicht auf die Lösung.

Folgendes Problem:

Ich muss doppelte Elemente in einer sehr großen Textdatei suchen.

Diese enthält als kurzen Auszug folgende Datei:

Code: Alles auswählen

19195;best_liste.csv.958
19204;best_liste.csv.959
12495;best_liste.csv.96
19180;best_liste.csv.960
19207;best_liste.csv.961
19210;best_liste.csv.962
19213;best_liste.csv.963
19214;best_liste.csv.964
19216;best_liste.csv.965
19224;best_liste.csv.966
19272;best_liste.csv.979
12506;best_liste.csv.98
19224;best_liste.csv.8875
Ich möchte nun nach doppelten Elementen vor dem ; suchen.
Und mir diese wenn sie öfters als 1x in der Datei vorkommen anzeigen lassen.

Allerdings klappt das ganze nicht so wie ich mir das denke.

Code: Alles auswählen

testfile = []
with open ( tfile, 'r') as orderlist:
#       print orderlist.readlines()
        ordernumbers = orderlist.readlines()
        for n1 in ordernumbers:
#               print n1 # n1 = index ganze liste
                k1= str(n1).split(';')
#               print k1[0]
                testfile.append(k1[0])
                for elem in testfile:
                        count = 0
                        if elem in n1:
                                count = count +1
                        else:
                                pass
                if count >= 2:
                        print elem
                else:   
                        pass    
Das komische ist wenn ich
if count >= 2:
auf
if count >= 1:
stelle bekomme ich den gesamten Listenindex angezeigt.

Stehe da gerade etwas auf dem Schlauch und weiß nicht wirklich weiter.
Hab mir auch set() angeschaut, allerdings scheint das nicht geeignet zu sein, da ich die doppelten elemente nicht auslöschen möchte sondern sie mir anzeigen möchte.
BlackJack

Freitag 2. November 2012, 11:51

@taake: Du könntest zwei `set`\s verwenden, eines in dem alle bisher gesehenen Nummern gespeichert werden. Das wird für jede Nummer vorher geprüft und wenn die Nummmer schon vorhanden ist, wird sie in das zweite `set` geschrieben. Da sind dann alle drin, die mehr als einmal vorkommen.

Oder du verwendest ein Wörterbuch das Nummern auf Wahrheitswerte abbildet, ob eine Nummer mehr als einmal gesehen wurde.

Oder gleich `collections.Counter`. Da hast Du dann eine Abbildung von Nummern auf Anzahl.

Wenn die Textdatei sehr gross ist, möchtest Du vielleicht auch kein `readlines()` ausführen und damit die komplette Datei auf einmal in den Speicher laden, sondern die Zeilen einzeln einlesen und verarbeiten.

Und was ist komisch daran, dass Du alles angezeigt bekommst, wenn Du auf ``>= 1`` prüfst? Einmal *muss* ja jeder Eintrag gefunden werden, der in der Liste enthalten ist.
taake
User
Beiträge: 124
Registriert: Donnerstag 14. Oktober 2010, 08:49

Freitag 2. November 2012, 12:40

Danke @Blackjack

Muss ich mal schauen ob ich für das mit dem set() irgendwo ein beispiel finde, wo ich etwas abkupfern kann.
Leider erschließt es sich mir nicht ganz aus dem beispiel im Wiki wie das mit zwei set()'s genau gesehen soll.
Werde da mal schauen.

Achja war etwas falsch formuliert mit den counts.
Was ich meinte der >= 1 zeigt mir alle der >=2 zeigt überhaupt nichts.
Obgleich es defintiv doppelte einträge in der Datei gibt.
Das verwirrt mich etwas.
taake
User
Beiträge: 124
Registriert: Donnerstag 14. Oktober 2010, 08:49

Freitag 2. November 2012, 13:08

Das eigentlich Problem hab ich jetzt lösen können.


Allerdings die Frage mit dem count 1 bzw count 2 stellt sich mir immer noch.

Code: Alles auswählen

testfile = []
mehrfach = []
with open ( tfile, 'r') as orderlist:
        ordernumbers = orderlist.readlines()
        for n1 in ordernumbers:
                k1= str(n1).split(';')
                testfile.append(k1[0])
        i=0
        while i < len(testfile):
                if testfile.count(testfile[i])>1:
                        mehrfach.append(testfile[i])
                i+=1
        for e in set(mehrfach):
                print e

Sirius3
User
Beiträge: 10875
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 2. November 2012, 13:12

Hallo taake,

Du setzt in jedem Schleifendurchgang count auf 0!
Ein else-Zweig der nur pass enthält ist überflüssig und
verhindert meiner Meinung nach das flüssige lesen.
Listen kennen count. Statt der for-Schleife

Code: Alles auswählen

count=testfile.count(k1[0])
Vielleicht gefällt Dir auch diese Ausgabe:

Code: Alles auswählen

with open(tfile, 'r') as orderlist:
    ordernumbers = orderlist.readlines()
    testfile=[n.split(';')[0] for n in ordernumbers]
    for k1 in sorted(set(testfile)):
        cnt=testfile.count(k1)
        if cnt>1: print '%dx %s'%(cnt,k1)
Grüße
Sirius
Benutzeravatar
pillmuncher
User
Beiträge: 1154
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Freitag 2. November 2012, 14:30

@taake: Mach dir halt das Leben nicht so schwer.

Ab Python 2.7, ungestestet:

Code: Alles auswählen

from collections import Counter

with open(tfile, 'r') as lines:
    tally = Counter(line.split(';')[0] for line in lines)
    for number, count in tally.iteritems():
        if count > 1:
            print number
Für ältere Pythons hilft ein:

Code: Alles auswählen

$ easy_install counter
in der Shell und dann natürlich:

Code: Alles auswählen

from counter import Counter
...
In specifications, Murphy's Law supersedes Ohm's.
Antworten