Abgleich zweier Zeilen

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
x1334
User
Beiträge: 13
Registriert: Mittwoch 13. Juni 2012, 12:34

Hallo.

Ich habe folgendes Szenario:

Inputdatei hat den Inhalt:

essen Fisch 30 Kabeljau
speisen Fisch 4 Kabeljau
verspeisen Fisch 9 Krabbe
essen Fisch 44 Krabbe

Daraus will ich machen:

essen Fisch 74 Kabeljau,Krabbe
speisen Fisch 4 Kabeljau
verspeisen Fisch 9 Krabbe

Sprich: Wenn Verb+Nomen gleich ist, Zahlen aufaddieren und die Nomen dahinter in dieselbe Zeile schreiben.
Bisher habe ich das mit einem Dictonaryumweg gelöst, funktioniert auch, aber ich kriege den hinteren Teil (das nach den Zahlen) nicht mit, da ich dann als value keinen INT mehr habe um das ganze zu addieren.

Bisheriger Code:

Code: Alles auswählen

splitter_file2 = {}

for line in dupl_file2:
    verb,nomen,freq = line.split()
    merge = verb+"#"+nomen
    if merge in splitter_file2:
        comb_freq = int(splitter_file2[merge]) + int(freq)
        splitter_file2[merge] = comb_freq
    else:
        splitter_file2[merge] = freq

for key in splitter_file2:
	rem_file2.write(key + " " + str(splitter_file2[key]) + "\n")

Später das ganze dann einfach wieder aufgesplittet mit .replace("#", " ")
Habt ihr eine Idee wie ich das am Besten lösen könnte?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Vielleicht ungefähr so?

Code: Alles auswählen

from collections import defaultdict

inp="""essen Fisch 30 Kabeljau
speisen Fisch 4 Kabeljau
verspeisen Fisch 9 Krabbe
essen Fisch 44 Krabbe
essen Fisch 10 Kabeljau"""

verb_nouns = defaultdict(int)
items = defaultdict(set)

for line in inp.splitlines():
    verb, noun, num, item = line.split()
    vn = ' '.join((verb, noun))
    verb_nouns[vn] += int(num)
    items[vn].add(item)

result = ['%s %s %s' % (k, verb_nouns[k], ','.join(items[k])) for k in verb_nouns]
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: und jetzt noch (verb, noun) nicht joinen sondern das Tuple als Key fürs Dictionary benutzen.

Nur so zum Spaß objektorientiert:

Code: Alles auswählen

from collections import defaultdict

inp="""essen Fisch 30 Kabeljau
speisen Fisch 4 Kabeljau
verspeisen Fisch 9 Krabbe
essen Fisch 44 Krabbe
essen Fisch 10 Kabeljau"""

class NumSet(object):
    def __init__(self, num=0, *items):
        self._num = num
        self._set = set(items)

    def __iadd__(self, other):
        if not isinstance(other,NumSet):
            raise ValueError('incompatible types')
        self._num += other._num
        self._set.update(other._set)
        return self

    def __str__(self):
        return '%i %s'%(self._num, ','.join(self._set))

verb_nouns = defaultdict(NumSet)

for line in inp.splitlines():
    verb, noun, num, item = line.split()
    verb_nouns[verb,noun] += NumSet(int(num),item)

print '\n'.join('%s %s %s'%(key+(item,)) for key,item in verb_nouns.iteritems())
BlackJack

@Sirius3: Bei der Ausnahme bei `__iadd__()` könnte man argumentieren, dass es dem „duck typing” entgegensteht. Auf jeden Fall ist es die falsche Ausnahme — mit dem Fehlertext sollte es ein `TypeError` sein.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Zudem könnte man die Attribute mal umbenennen und die Unterstriche entfernen... ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
x1334
User
Beiträge: 13
Registriert: Mittwoch 13. Juni 2012, 12:34

Super! Funktioniert perfekt, vielen Dank - wieder was gelernt!!
Antworten