Seite 1 von 1

Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 19:19
von Nobuddy
Hallo zusammen,

Um einen Vergleich in einem Dictionary machen zu können, muß ich die vierte Spalte dieser Datei (Ausschnitt) bearbeiten.

Code: Alles auswählen

03	127	0135	PATCH-PANEL	PATCH-PANEL,-DIGITUS			
03	127	0172	PATCH-PANEL	PATCH-PANEL,-EQUIP			
03	127	0331	PATCH-PANEL	PATCH-PANEL,-LOGILINK			
03	127	0568	PATCH-PANEL	PATCH-PANEL,-TELEGÄRTNER			
03	128	0000	INDUSTRIAL-ETHERNET,-PASSIV	PATCHKABEL,-KAT.5,-TELEGÄRTNER			
03	128	0000	INDUSTRIAL-ETHERNET,-PASSIV	PATCHKABEL,-KAT.7,-TELEGÄRTNER			
03	128	0000	PATCHKABEL,-KAT.5E,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.5E,-DIGITUS			
03	128	0000	PATCHKABEL,-KAT.5E,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.5E,-DRAKA			
03	128	0000	PATCHKABEL,-KAT.5E,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.5E,-EQUIP			
03	128	0000	PATCHKABEL,-KAT.5E,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.5E,-LOGILINK			
03	128	0000	PATCHKABEL,-KAT.6,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.6,-DRAKA			
03	128	0000	PATCHKABEL,-KAT.6,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.6,-LOGILINK			
03	128	0000	PATCHKABEL,-KAT.7,-ROLLENWARE	PATCHKABEL,-ROLLENWARE,-KAT.7,-DRAKA			
03	128	0135	INTERNET-KAMERAS-/-WEBCAMS	INTERNET-KAMERAS-/-WEBCAMS,-DIGITUS			
03	128	0214	INTERNET-KAMERAS-/-WEBCAMS	INTERNET-KAMERAS-/-WEBCAMS,-GENIUS		
Dabei muß ich den letzten Teil (Herstellernamen) der vierten Spalte verschwinden lassen.
Beispiel:
INTERNET-KAMERAS-/-WEBCAMS,-DIGITUS
INTERNET-KAMERAS-/-WEBCAMS
Da es öfters vorkommt, mehr als nur ein Komma in dem String zu haben, das berücksichtigt werden muß, habe ich ein Konstrukt dazu erstellt

Code: Alles auswählen

with codecs.open(subgroupindex_path, "r") as infile:
    reader = csv.reader(infile, delimiter="\t", quotechar="^")

    subgroupindex = {}
    for line in reader:
       subgroupindex[line[0], line[1]] = line[2]


with codecs.open(basegroup_path, "r") as infile:
    reader = csv.reader(infile, delimiter="\t", quotechar="^")

    daten = []
    for item in reader:        
        if ',' in item[4]:
            y = item[4].count(',')
            y = y - 1

        if y > 1:
            a = item[4].split(',')[:y]
            b = (item[0], a)
            p = subgroupindex.get(b, '---')
        else:
            a = item[4].split(',')[0]
            b = (item[0], a)
            p = subgroupindex.get(b, '---')
Problem dabei, ist dieser Bereich

Code: Alles auswählen

        if y > 1:
            a = item[4].split(',')[:y]
            b = (item[0], a)
            p = subgroupindex.get(b, '---')
Hier kommt als Fehlermeldung:
TypeError: unhashable type: 'list'
Ich habe mir das eigentlich so vorgestellt, daß wie in diesem Beispiel
PATCHKABEL,-ROLLENWARE,-KAT.5E,-DIGITUS
drei Kommas enthalten sind.
Also lasse ich die Kommas im String zählen, ziehe vom Ergebnis -1 ab und definiere den neuen String.
Anschließend möchte ich dieses Ergebnis in einem Dictionary vergleichen können.

Was mache ich falsch, bzw. wo ist mein Denkfehler?

Grüße Nobuddy

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 19:52
von Hyperion
Du versuchst ein Objekt, welches nicht gehasht werden kann (hier eine Liste) als Schlüssel für ein Dict zu verwenden. Das passiert in der zweiten Zeile:

Code: Alles auswählen

b = (item[0], a)
p = subgroupindex.get(b, '---')
``b`` ist eben nicht ``hashable`` - Du willst es aber als Schlüssel verwenden. Zwar ist das hier nur eine Abfrage, die kann aber eh nicht sinnvoll sein, da so ein Schlüssel natürlich auch nicht in ein Dict eingefügt werden kann ;-)

Beispiele:

Code: Alles auswählen

>>> l = [1, 2, 3]
>>> d = {}
>>> d.get(l)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    d.get(l)
TypeError: unhashable type: 'list'
>>> foo = ("bar", l)
>>> d = {}
>>> d.get(foo)
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    d.get(foo)
TypeError: unhashable type: 'list'
>>> type(foo)
2: <class 'tuple'>
Der Fehler dürfte übrigens auch im ``else``-Zweig auftreten ;-)

Was mir aber nicht klar ist: Wieso machst Du da so viele Verrenkungen bezüglich des Parsens? Woran erkennst Du denn exakt eine Firma? Dafür muss es doch Regeln geben! Mir ist das bisher unklar, aber das sollte def. eleganter gehen.

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 19:54
von /me
Nobuddy hat geschrieben:Was mache ich falsch, bzw. wo ist mein Denkfehler?
Ich finde den ganzen Ansatz zu kompliziert. Ich würde einfach den String mit split auseinandernehmen und dabei das Komma als Trenner wählen. Anschließend packt man dann alles ohne den letzten Teil wieder zusammen.

Code: Alles auswählen

>>> data = 'PATCHKABEL,-ROLLENWARE,-KAT.7,-DRAKA'
>>> ','.join(data.split(',')[:-1])
'PATCHKABEL,-ROLLENWARE,-KAT.7'
Falls es vorkommen kann, dass kein Komma im String vorhanden ist, dann sollte man das vorher feststellen und in dem Fall gar nichts tun.

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 20:09
von Nobuddy
Ja, manches mache ich wirklich kompliziert, das merke ich meistens hinterher ... :wink:

Hyperion, die Regel ist die, daß in Spalte 4 immer als letztes der Hersteller, getrennt durch ein ',-' enthalten ist.

Meine Lösung, welche funktioniert

Code: Alles auswählen

with codecs.open(subgroupindex_path, "r") as infile:
    reader = csv.reader(infile, delimiter="\t", quotechar="^")

    subgroupindex = {}
    for line in reader:
       subgroupindex[line[0], line[1]] = line[2]


with codecs.open(basegroup_path, "r") as infile:
    reader = csv.reader(infile, delimiter="\t", quotechar="^")

    daten = []
    for item in reader:
        if ',-' in item[4]:
            y = item[4].count(',-')
            a = item[4].split(',-')[y]
            z = item[4].replace(',-' + a, '')

        b = (item[0], z)
        p = subgroupindex.get(b, '---')
Allerdings ist die Lösung von /me, kürzer und eleganter.
Werde diese ausprobieren!

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 20:21
von nomnom
Das geht meiner Meinung nach noch eleganter. ;)

Code: Alles auswählen

In [2]: data = 'PATCHKABEL,-ROLLENWARE,-KAT.7,-DRAKA'

In [3]: data.rpartition(',')[0]
Out[3]: 'PATCHKABEL,-ROLLENWARE,-KAT.7'

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Donnerstag 9. Februar 2012, 20:30
von /me
Nobuddy hat geschrieben:Werde diese ausprobieren!
Eine Alternative könnte es auch noch sein das letzte Komma im String zu bestimmen und dann mit dem passenden Slice zu arbeiten.

Code: Alles auswählen

pos = data.rfind(',')
if pos >= 0:
    data = data[:pos]
Da ist die Prüfung auf ein vorhandenes Komma gleich eingebaut.

Edit: @nomnom: An partition hatte ich ja gedacht, aber rpartition war mir entfallen. Das ist für mich die beste Variante.

Re: Dictionary - Fehlermeldung bei Wertübergabe

Verfasst: Freitag 10. Februar 2012, 16:12
von Nobuddy
Hallo zusammen,

/me, habe zuerst Deinen Vorschlag ausprobiert

Code: Alles auswählen

pos = data.rfind(',')
if pos >= 0:
    data = data[:pos]
, was schon wesentlich kürzer als mein Konstrukt ist und prima funktionierte.

Jedoch der Tip von nomnom, ist nochmals kürzer und funktioniert auch prima, wie Du selbst geschrieben hast.

Code: Alles auswählen

data.rpartition(',')[0]
Mit dem

Code: Alles auswählen

data = 'PATCHKABEL,-ROLLENWARE,-KAT.7,-DRAKA'
data = data.rpartition(',')[-1].replace('-', '')
erhalte ich dann diese Ausgabe
'DRAKA'
Danke für Euren Input! :wink:

Grüße Nobuddy