Suche Hilfe : String.replace() + dicts

Code-Stücke können hier veröffentlicht werden.
Antworten
Caskuda
User
Beiträge: 26
Registriert: Sonntag 15. März 2020, 22:09

Servus,

erster Post hier und ggf. im Falschen Teilbereich?

Ich wollte in einigen alten Dateien eine Reihe von Strings austauschen.
Hierbei habe ich das Problem, dass in meinen Dicts teilweise die "keys" ein Substring eines anderen "keys" sind.

Hier ein anschauliches Beispiel:

Code: Alles auswählen

# Fehlerhafter Ansatz:
testline = 'ee eee ee eee ee'
dict= {'ee':'Test1','eee':'Test2'}
for key in dict:
    testline=testline.replace(key,dict.get(key))
print(testline)

testline = 'ee eee ee eee ee'
dict= {'eee':'Test2','ee':'Test1'}
for key in dict:
    testline=testline.replace(key,dict.get(key))
print(testline)
# liefert nicht immer das gewünschte Resultat. 
# Output : Test1 Test1e Test1 Test1e Test1

#Zielführend, aber ich setze pro "key"-Länge ein eigenes Dict und der Code wird unschön: 
testline = 'ee eee ee eee ee'
d1 = {'ee':'Test1'}
d2 = {'eee':'Test2'}
for key in d2:
    testline = testline.replace(key,d2.get(key))

for key in d1:
    testline = testline.replace(key,d1.get(key))
print(testline)
#Output: Test1 Test2 Test1 Test2 Test1

Dicts bieten meines Wissens nach keine Möglichkeit nach Länge zu sortieren, oder übersehe ich hier schlicht etwas?
Kann ich anderweitig garantieren, dass ich zuerst nach den "keys" größter Länge suche?

Der momentane Lösungsansatz ist bei kleinen Dicts praktikabel, aber wird bei großen Dicts schnell unübersichtlich.

Kennt jemand eine elegantere Lösung als das ursprüngliche dict auszulesen, und sich dicts unterschiedlicher Länge zu erzeugen?

Freue mich über Denkanstöße.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du mußt ja auch nicht das Dict sortieren, sondern nur die Keys.

Code: Alles auswählen

keys = sorted(the_dict, key=len, reverse=True)
Caskuda
User
Beiträge: 26
Registriert: Sonntag 15. März 2020, 22:09

@Sirius3 :

Tausend Dank! Jetzt dämmert es mir. Ich bekomme dann eine geordnete Liste mit den Key-Einträgen, über die ich iteriere, und nicht
über das dict selbst.

Code: Alles auswählen

testline = 'ee eee ee eee ee'
dict= {'eee':'Test2','ee':'Test1'}
keys = sorted(dict, key=len, reverse=True) # liefert Liste der sortieren Keys
for key in keys:
    testline= testline.replace(key, dict.get(key))
print(testline)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

`get` sollte man nur benutzen, wenn es auch Sinn macht, den Default-Wert zu benutzen. Das ist bei Dir nicht der Fall.
`dict` ist der Name des dict-Typs und sollte nicht durch eine Variable überdeckt werden.

Code: Alles auswählen

testline = 'ee eee ee eee ee'
replacements = {'eee':'Test2','ee':'Test1'}
keys = sorted(replacements, key=len, reverse=True) # liefert Liste der sortieren Keys
for key in keys:
    testline = testline.replace(key, replacements[key])
print(testline)
das ganze einfacher per Regulärem Ausdruck:

Code: Alles auswählen

import re
pattern = '|'.join(map(re.escape, sorted(replacements, key=len, reverse=True)))
testline = re.sub(pattern, lambda m:replacements[m.group(0)], testline)
Antworten