Seite 1 von 1

Textstring suchen! aber wie?

Verfasst: Dienstag 4. November 2008, 10:37
von Malibow
Hallo an alle Pythonuser und Freunde,
habe ein Problem und zwar...

habe 2 Listen von Tupeln!
Liste A: enthält ['0x016', '0x033' ...]
Liste B: enthält ['0x016=blablabla', '0x017=text']

Liste A ist vorgegeben und Liste B wird aus einer Datei erzeugt.

Ich möchte jetzt überprüfen ob die Elemente Aus Liste A in Liste B vorzufinden sind.
Falls ja möchte ich Das gleiche Element samt Text Ausgeben.
Habt ihr ne einfache Idee wie ich da rangehen könnte?
gibts ne entsprechende Suchfunktion in Python?

Verfasst: Dienstag 4. November 2008, 10:43
von .robert
Hast du Einfluss darauf, wie die Listen erstellt werden?

Wenn ja, dann mach aus Liste B ein Dictionary, das dann etwa so aussieht:

Code: Alles auswählen

listeB = {'0x016' : 'blablabla', '0x017' : 'text', ... }
dann kannst du einfach über den Schlüssel auf die Werte zugreifen:

Code: Alles auswählen

for i in listeA:
    if listeB.has_key(i):
        print listeB[i]
    else:
        print "Wert %s nicht in Liste B" % i
...so in etwa

Verfasst: Dienstag 4. November 2008, 10:52
von Malibow
ähm ja habe Einfluss darauf...
Liste B wird aus einer Textdatei erstellt die zuvor nur über Zeilen getrennt war.. mal schauen ob ich das hinbekomm ;-)

ging ja brutal schnell die Antwort danke erstmal

Verfasst: Dienstag 4. November 2008, 12:20
von Malibow
hat mir noch jemand nen tipp wie ich des dictionary aus der Textdatei am einfachsten erstelle?

Zur info
Textdatei ist wie folgt aufgebaut
0x016=blablabla
0x017=text
.
.
.

Verfasst: Dienstag 4. November 2008, 12:33
von .robert
du wolltest doch schauen ob du das hin bekommst, wo sind denn deine Ansätze? :wink:

Und wo hast du Probleme?

Das öffnen der Datei wirst du ja hinbekommen, oder?
Dann nimmst du einfach jede Zeile, wie vorher auch schon, aber packst die nicht so in eine Liste, sondern splittest sie an dem "=" und fügst dem Dictionary ein neues Element hinzu. Der Key ist dann das was vor dem "=" steht, und das Value das dahinter.

Aber ich frage ich grade, werden die Einträge, die nicht in Liste A sind, überhaupt später noch benötigt? Wenn nicht, könntest du direkt beim einlesen mit "if wert in listeA:" filtern... nur so als Gedanke...

Verfasst: Dienstag 4. November 2008, 13:09
von .robert
Na gut... :)

Natürlich könnte man hier auch mit csv arbeiten, obwohl sich die Frage stellt ob das sinnvoll wäre:

Code: Alles auswählen

import csv
csv.register_dialect('bla', delimiter='=', quoting=csv.QUOTE_NONE)
raw_data = csv.reader(open("dateiname.tx", "rb"), 'bla')
data = {}
for row in raw_data:
    data[row[0]]=row[1]

Verfasst: Dienstag 4. November 2008, 13:19
von .robert
Ohne den Gebrauch von csv sähe das etwa so aus:

Code: Alles auswählen

data = {}
f = file('dateiname.txt', 'r')

for line in f.readlines():
    d = line.split('=')
    data[d[0]]=d[1].strip()

Verfasst: Dienstag 4. November 2008, 13:49
von HWK
Etwas einfacher:

Code: Alles auswählen

f = file('dateiname.txt', 'r')
data = dict(line.strip().split('=') for line in f)
f.close()
MfG
HWK

Verfasst: Dienstag 4. November 2008, 13:53
von BlackJack
@.robert: `readlines()` liesst die gesamte Datei auf einen Schlag in den Speicher, das ist hier nicht nötig. Ausserdem sollte man die Datei auch wieder schliessen.

Code: Alles auswählen

f = open('dateiname.txt', 'r')
data = dict(line.rstrip().split('=', 1) for line in f)
f.close()

Verfasst: Dienstag 4. November 2008, 13:57
von .robert
Danke für die Verbesserung, an das schließen hatte ich jetzt wirklich nicht gedacht :)

Verfasst: Dienstag 4. November 2008, 14:02
von HWK
@BlackJack: split('=', 1) ist natürlich sicherer. Ich würde aber lieber strip als rstrip verwenden, da führende Whitespaces in einem Key wohl nicht so sinnvoll sind.
MfG
HWK

Verfasst: Dienstag 4. November 2008, 14:51
von Malibow

Code: Alles auswählen

def ausgeben(listeA):
      try:
            datei = file("text.txt")
            fehlercodes = datei.readlines()
            datei.close()
      except:
            print "Kann Datei nicht oeffnen!"
      listeB={}
      for eintrag in fehlercodes:
            l_eintrag = eintrag.split("=")
            listeB[l_eintrag[0]] = l_eintrag [1:]

      hilfsliste=[]
      for i in listeA: 
          if listeB.has_key(i):
                hilfsliste.append(i+ str(listeB[i]))

          else: 
              print "Wert %s nicht in der Fehlerliste " % i
      return hilfsliste

hab jetzt mal des so zusammengebastelt!

scheint hier ja ne Menge los zu sein im Forum......

danke allen Mithelfenden!

jetzt gibts noch ein Problem und zwar fehlen in ListeA die führenden Nullen der Hexzahlen d.h. dass er mir jedesmal die Meldung bringt dass 0x15 aus Liste A nicht in Liste B 0x00015 vorhanden ist:

wie könnte ich die eliminieren?


@Blackjack warum sollte ich nicht die ganze Datei einlesen sind ca 100 Zeilen

Verfasst: Dienstag 4. November 2008, 15:12
von HWK
Wandele die Hexzahlen in Ints mit int(zahl, 16) um.
Übrigens: Deine Funktion wird crashen, wenn Du die Datei nicht öffnen kannst, da dann fehlercodes nicht definiert ist. Du solltest also den Fehler nicht nur ausgeben, sondern auch darauf reagieren. Außerdem solltest Du nur bestimmte Exceptions abfangen, z.B. mit

Code: Alles auswählen

except IOError:
MfG
HWK

Verfasst: Dienstag 4. November 2008, 15:43
von sevven
bin zwar noch lange kein profi, aber hier mal meine ansicht dazu. Umgeht das extra umspeichern nach dem einlesen und der vorschlag vom Bild is auch dabei.
ungetestet:

Code: Alles auswählen

def ausgeben(listeA):
      try:
            datei = open("text.txt","r")
      except IOError:
            print "Kann Datei nicht oeffnen!"
      
      listeB=[]
      while 1:
            line = datei.readline().strip()
            if not line: # equal to 'end of file'
                  break
            else:
                  if (line.split("=")[0]) in listeA:
                        print "%s ist in Liste!" % line
                        listeB.append(line)
                  else:
                        print "%s ist nicht in Liste" % line
      datei.close()
      return listeB

Verfasst: Dienstag 4. November 2008, 16:00
von numerix
@sevven:

Die while-Konstruktion zum Auslesen der Datei ist nicht "python-like". Das geht in Python VIEL eleganter:

Code: Alles auswählen

for zeile in datei:
    # mach was mit zeile
Es wird einfach über alle Zeilen der Datei iteriert, das Zeilenende brauchst du gar nicht explizit zu prüfen.

Verfasst: Dienstag 4. November 2008, 16:26
von Malibow
HWK hat geschrieben:Wandele die Hexzahlen in Ints mit int(zahl, 16) um.
Übrigens: Deine Funktion wird crashen, wenn Du die Datei nicht öffnen kannst, da dann fehlercodes nicht definiert ist. Du solltest also den Fehler nicht nur ausgeben, sondern auch darauf reagieren. Außerdem solltest Du nur bestimmte Exceptions abfangen, z.B. mit

Code: Alles auswählen

except IOError:
MfG
HWK
erstmal danke für deinen Tipp:

habe das jetzt versucht die Zahlen zu konvertieren:

Code: Alles auswählen

hex(int(zahl,16))
gibt es bei dieser Schreibweise irgendwie die Möglichkeit zu sagen, dass die Hexzahl mindestens 0x000123 so aussehen soll...
weil 0x123 habe ich eh schon vorliegen
und ich weiß nicht an welcher stelle ich in meinem Code die Keys ändern könnte..

Verfasst: Dienstag 4. November 2008, 16:29
von HWK

Code: Alles auswählen

>>> '0x%06X' % 0x123
'0x000123'
MfG
HWK

Verfasst: Dienstag 4. November 2008, 16:51
von Y0Gi
Der `IOError`-Handler greift nur beim Öffnen der Datei, nicht beim Lesen.

Wenn du in einer Schleife in einer `if`-Bedingung ein `break` machst, braucht es danach kein `else` mehr.

Verfasst: Dienstag 4. November 2008, 16:56
von Malibow
Danke allen Mithelfenden....

Problem gelöst....

kann ich den Threadtitel irgendwie umbenennen? und (gelöst) am Ende einfügen?

Verfasst: Dienstag 4. November 2008, 18:56
von Leonidas
Malibow hat geschrieben:kann ich den Threadtitel irgendwie umbenennen? und (gelöst) am Ende einfügen?
Kannst du schon (einfach Ursprungsbeitrag editieren), aber das wird hier nicht gerne gesehen. Falls dich die Gründe interessieren, nutz die Suchfunktion, wurde mindestens zweimal ausführlich diskutiert.