Seite 1 von 1

Abgleich zweier Zeilen

Verfasst: Samstag 5. Januar 2013, 16:12
von x1334
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?

Re: Abgleich zweier Zeilen

Verfasst: Samstag 5. Januar 2013, 18:10
von kbr
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]

Re: Abgleich zweier Zeilen

Verfasst: Samstag 5. Januar 2013, 18:58
von Sirius3
@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())

Re: Abgleich zweier Zeilen

Verfasst: Samstag 5. Januar 2013, 22:16
von 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.

Re: Abgleich zweier Zeilen

Verfasst: Samstag 5. Januar 2013, 22:29
von Hyperion
Zudem könnte man die Attribute mal umbenennen und die Unterstriche entfernen... ;-)

Re: Abgleich zweier Zeilen

Verfasst: Sonntag 6. Januar 2013, 14:17
von x1334
Super! Funktioniert perfekt, vielen Dank - wieder was gelernt!!