Seite 1 von 1

Eine Funktion zum Vertauschen von Schlüssel und Wert (Dict.)

Verfasst: Sonntag 29. September 2002, 09:22
von ASCII158
Dieses Forum sieht so traurig aus ohne Beiträge, deswegen bekommt ihr hier mal was zum zerfleddern :wink::

Code: Alles auswählen

def swapdict(dict):
	"""swapdict(dict) -> dict
	Vertauscht die Schlüssel und Werte eines Dictionaries. Wenn ein Wert mehr als einmal vorkommt werden die dazugehoerigen Schlüssel in einer Liste mit diesem Wert verbunden.
	Turns value to key and the other way round. If a value appears more than one time the keys are set to a list and associated with the value."""
	
	import types
	redict={}
	for i in dict.keys():
		if dict[i] in redict.keys():
			if type(redict[dict[i]])==type(types.TupleType()):
				redict[dict[i]]+=(i,)
			else:
				redict[dict[i]]=(redict[dict[i]],i,)
		else:
			redict[dict[i]]=i
	return redict

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 11:23
von Voges
Hallo 111111!
ASCII158 hat geschrieben:Dieses Forum sieht so traurig aus ohne Beiträge, deswegen bekommt ihr hier mal was zum zerfleddern :wink::
Mein Vorschlag (allerding mit Listen, nicht mit Tupel):

Code: Alles auswählen

redict = {}
for key,value in dict.items():
    try:
        try:
            redict[value].append(key)
        except:
            redict[value] = [redict[value],key]
    except:
        redict[value] = key
Warum erst fragen (if), wenn man es doch gleich versuchen kann (try)?
Ok, im RL tut man sich dabei weh, wenn man gegen die Tür rennt und sie dann erst öffnet, aber dem Rechner ist das egal :-)

Jan

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 11:47
von ASCII158
Ich heisse 10011110! :lol:

Warum erst fragen (if), wenn man es doch gleich versuchen kann (try)?
Daran merkt man, dass man zulange mit Basic "rumgeschweinst" hat... :roll:

Ich bestehe aber weiterhin auf den Tuples:

Code: Alles auswählen

for key,value in dict.items(): 
		try: 
			try: 
				redict[value]+=(key,) 
			except: 
				redict[value] = (redict[value],key)
		except: 
			redict[value] = key

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 11:57
von Voges
Hallo 10001011!

[quote="ASCII158"]Ich heisse 10011110! :lol: [quote]
Für jahrelange Usenet-Nutzer wie mich sind diese k3wlen Pseudos in den Web-Foren etwas gewöhnungsbedürfig und meist auch der Hauptgrund, sie (die Web-Foren) zu meiden. Naja, nicht Euer Problem.

Jan

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 13:46
von Voges
Hallo!
ASCII158 hat geschrieben: Ich bestehe aber weiterhin auf den Tuples:
Was mir noch auffiel, da Du das Ganze wohl zur Wiederverwendung in eine Funktion packst. Um es etwas sauberer zu gestalten, sollte man nur die konkreten Exceptions bearbeiten, damit die anderen nach oben weitergereicht werden.

Code: Alles auswählen

        except TypeError:
            [...]
    except KeyError:
Zudem überblicke ich so auf die Schnelle nicht, was passiert, wenn im Ausgangs-Dictionary die Schlüssel und/oder Werte was anderes sind, als Strings oder Zahlenwerte, also z.B. Listen oder Dictionaries.

Jan

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 17:35
von ASCII158
Hi,
Voges hat geschrieben: Zudem überblicke ich so auf die Schnelle nicht, was passiert, wenn im Ausgangs-Dictionary die Schlüssel und/oder Werte was anderes sind, als Strings oder Zahlenwerte, also z.B. Listen oder Dictionaries.
Funktioniert alles, nur natürlich nicht Listen im Value, weil die kein Key werden können!

Re: Eine Funktion zum Vertauschen von Schlüssel und Wert (Di

Verfasst: Sonntag 29. September 2002, 18:51
von Voges
Hallo!
ASCII158 hat geschrieben:Funktioniert alles,
Leider nicht. xy-Koordinaten kommen ja häufig als Schlüssel vor. Und aus ...
dict = {(2,4):'rot',(1,3):'rot',(6,7):'blau',(2,5):'rot',(7,7):'gelb'}
... wird leider ...
{'blau': (6, 7), 'gelb': (7, 7), 'rot': (2, 4, (2, 5), (1, 3))

Da ist wohl doch noch etwas Feinarbeit nötig.

Jan

Oh...

Verfasst: Montag 30. September 2002, 13:09
von ASCII158
Darin liegt der Sinn dieses Forums, Fehler zu finden!

Aber eine Korrektur fällt mir dazu so auf die Schnelle auch nicht ein...

Verfasst: Mittwoch 28. Juli 2004, 18:48
von Dookie
Hallo,

mal den Thread wiederbeleb.
Mit Python ab Version 2.2 geht das tauschen von Schlüssel/Wert auch mit einem Einzeiler:

Code: Alles auswählen

test = {(1,3) : 'rot', (6,7) : 'blau', (7,7) : 'gelb', (4,6) : 'gruen'}
print dict([(b, a) for a, b in test.items()])
Nachteil, wenn Werte doppelt vorkommen, wird irgendein Paar genommen.


Gruß

Dookie

Verfasst: Mittwoch 28. Juli 2004, 20:04
von Milan
HI. Mit Python 2.4 gehts auch komplett mit Iteratoren :wink: . Allerdings dürfen nach wie vor keine Dicts oder Listen als Value vorkommen...

Code: Alles auswählen

test = {(1,3) : 'rot', (6,7) : 'blau', (7,7) : 'gelb', (4,6) : 'gruen'}
print dict( (b, a) for a, b in test.iteritems() )

Verfasst: Mittwoch 28. Juli 2004, 21:48
von Dookie
dat geht auch mit 2.3, hab an iteritems gar nicht gedacht :)


Gruß

Dookie

Verfasst: Donnerstag 29. Juli 2004, 08:25
von Milan
Hi. Schau es dir genau an :wink: --- es ist keine List Comprehension...

Verfasst: Montag 30. Mai 2005, 02:53
von Olliminatore
Dookie hat geschrieben:Hallo,
mal den Thread wiederbeleb.
[...]
Nachteil, wenn Werte doppelt vorkommen, wird irgendein Paar genommen.
Hat jemand eine Lösung ohne diesen Nachteil?

Also wenn ein Key doppelt ist soll dessen Value an den anderen angehängt werden.(also nicht gelöscht)

Verfasst: Montag 30. Mai 2005, 12:10
von gerold
Olliminatore hat geschrieben:
Dookie hat geschrieben: Nachteil, wenn Werte doppelt vorkommen, wird irgendein Paar genommen.
Hat jemand eine Lösung ohne diesen Nachteil?
Also wenn ein Key doppelt ist soll dessen Value an den anderen angehängt werden.(also nicht gelöscht)
Hi!
Ist das ursprüngliche, erste Beispiel nicht das was du brauchst?
lg
Gerold
:-)

mit Liste

Verfasst: Montag 30. Mai 2005, 16:38
von Olliminatore
Ja fast :oops: war schon müde, (dachte sie hat kleinen Fehler)
Ausserdem brauche eine Funktion die einfach und schnell ist, da ich mit grossen Zahlenwerten arbeite :).
python 2.2
Hier mein Vorschlag für ein einfaches dict (type müsste egal sein)habe halben Tag dran gesessen :shock:

Code: Alles auswählen

## Dictionary zu Liste wandeln 
MapL = dict.iteritems()
## Schluessel/Werte umdrehen und Werte in Liste wandeln
MapL= [(b, [a]) for a, b in MapL]
MapL.sort()    ## Ordnung muss sein
Listshort=[("",[""])]

for value, key in MapL:
    if value != Listshort[-1][0]:
        Listshort.append([value, key])
    else:
        Listshort[-1][1].extend(key)

## und wieder zurück von Liste zu Dictonary
redict=dict(Listshort[1:])
geht auch oder? Kann sein dass es noch einfacher geht. Teste jetzt noch bisschen...
(value und key namen könnten ungünstig gewählt sein, halt umgedreht) :roll:

edit: (als member ist echt komfortabler hier)
ohne else geht auch, weiss aber nicht ob dass schneller ist mit pop(), vieleicht geht nochn Einzeiler? :P (list comprehension ist noch nicht so mein ding)

Code: Alles auswählen

[...snipped...]
habs mit Dookies List Benchmark getestet. Die pop() Variante war 4mal langsamer :!:

Verfasst: Montag 30. Mai 2005, 21:57
von Olliminatore
Habe mal alle Varianten mitn Benchmark durchgetestet.
ASCII158: mit try: und tuple war (minimal schlechter) gleich Voges: mit list.
Interessant ist mit

Code: Alles auswählen

        except TypeError:
            [...]
    except KeyError:
um 1/3 schneller war :!:

Wobei meine Variante (für meine Zwecke) noch 7mal schneller war als Diese .
Scheinbar weil ich keine Type/Key Abfrage mache.

Verfasst: Donnerstag 2. Juni 2005, 15:36
von Olliminatore

Code: Alles auswählen

def dictinvert(d):
    inv = {}
    for k, v in d.iteritems(): inv.setdefault(v, []).append(k)
    return inv
Das ist was ich gesucht habe(dict) ! :D
Da gilt wieder: Wer sucht der findet , aber wann!?
Meine List Variante ist aber immernoch doppelt so schnell.