Aus einer Liste doppelte Einträge entfernen (Einzeiler)

Code-Stücke können hier veröffentlicht werden.
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Hierbei bleibt allerdings die Reihenfolge nicht erhalten.

Python das fast wie Perl ausschaut :D

Code: Alles auswählen


listD= reduce(lambda d,v:(d.setdefault(v,None),d)[1], listD, {}).keys()

[/code]
Gast

Hier bleibt die Sortierung erhalten.

Code: Alles auswählen

longList= ['A','B','A','C','D','A','E','F','D']
redList=map(lambda tpl:tpl[0], filter(lambda tpl: longList.index(tpl[0])==tpl[1], zip(longList, xrange(len(longList)))))
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Habe jetzt noch eine Lösung, bei der die Sortierung erhalten bleibt, und nur einmal eine Liste erstellt wird.

Code: Alles auswählen

reduce(lambda lP,itemP: (itemP not in lP) and lP.append(itemP) or lP, LONGLIST, [])
cu beyond
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo,

hier mal eine Python2.3 Version, leider bleibt die Sortierung auch hier nicht erhalten.

Code: Alles auswählen

>>> from sets import Set

>>> longList = ['A', 'B', 'A', 'C', 'D', 'A', 'E', 'F', 'D']
>>> list(Set(longList))
['A', 'C', 'B', 'E', 'D', 'F']
Dookie
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!

Mein Vorschlag, wenn die Sortierung erhalten bleiben soll (enumerate() gibt es ab 2.3):

Code: Alles auswählen

longList = ['A', 'B', 'A', 'C', 'D', 'A', 'E', 'F', 'D'] 
print [item for i,item in enumerate(longList) if i == "".join(longList).find(item)]
Sehr performant wird das aber wegen des join() nicht sein. Aber Einzeiler war gefragt ;-)
Jan
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Einen hab' ich noch:

Code: Alles auswählen

[item for i,item in enumerate(longList) if item not in longList[:i]]
Jan
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

und für die nich 2.3er übersetzt (mir fällt nix weiter ein :wink: ):

Code: Alles auswählen

[l[i] for i in xrange(len(l)) if l[i] not in l[:i]]
Zuletzt geändert von Milan am Donnerstag 9. Oktober 2003, 12:39, insgesamt 1-mal geändert.
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

:D

Hätte gar nicht gedacht, daß es soviele Möglichkeiten dafür gibt.
GM

Man kann auch die Liste in ein Dictionary und zurück wandeln (Sortierung geht flöten):

dict.fromkeys([1,2,3,4,1], None).keys()
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Dookie hat geschrieben:Hallo,

hier mal eine Python2.3 Version, leider bleibt die Sortierung auch hier nicht erhalten.

Code: Alles auswählen

>>> from sets import Set

>>> longList = ['A', 'B', 'A', 'C', 'D', 'A', 'E', 'F', 'D']
>>> list(Set(longList))
['A', 'C', 'B', 'E', 'D', 'F']
Dookie
Da ja jetzt Python2.4 angesagt ist, geht es noch kürzer:

Code: Alles auswählen

Python 2.4 (#1, Dec  1 2004, 11:09:16)
[GCC 3.3.2 20031022 (Red Hat Linux 3.3.2-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> longList = ['A', 'B', 'A', 'C', 'D', 'A', 'E', 'F', 'D']
>>> print list(set(longList))
['A', 'C', 'B', 'E', 'D', 'F']
>>>

Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Warum braucht man dazu v2.4 ???

Außerdem ist die Sortierung doch auch nicht wirklich richtig...
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
jens hat geschrieben: Warum braucht man dazu v2.4 ???
Na dann versuchs mal mit 2.3.
jens hat geschrieben: Außerdem ist die Sortierung doch auch nicht wirklich richtig...
Hat keiner behauptet. Ist ja nur die 2.4-Version von Dookies Variante.

Gruß, mawe
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

jens hat geschrieben:Warum braucht man dazu v2.4 ???

Außerdem ist die Sortierung doch auch nicht wirklich richtig...
Weil sets jetzt in C implementiert sind und direkt über set() als builtin verfügbar sind.

fs111
Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Scheisse nochmal, ich muss noch viel lernen. Was ihr da in einer Zeile gebastelt habt, dafür brauchte ich so an die 10 oder so :oops:
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

*hehe*, das kommt schon noch :wink: Die schönste und resourcenspaarenste ist die von Voges auf 2.4 übersetzt. Bei der bleibt dann die Sortierung auch erhalten, was sehr vorteilhaft sein kann. Deswegen nehm ich weder dicts noch sets (welche ja auch nur dicts mit speziellen Methoden sind)

Code: Alles auswählen

(item for (i,item) in enumerate(longList) if item not in longList[:i])
Dumm nur, das longList selbst kein Iterator sein kann, da die kein slicing unterstützen.
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Tja mir ist im nachhinein aufgefallen, dass ich so dumm gar nicht bin, da mein Code die Liste flattet aber gleichzeitig auch das Vorkommen der einzelnen Tokens zählt (brauchte den Algorithmus für meinen Tokenizer). Hier mal der Code, Verbesserungsvorschläge gerne gesehen:

Code: Alles auswählen

def count_words(liste):
	liste.sort()
	current_pos = 0
	first_pos = 0
	out_liste = []
	nr_liste = []
	list_length = len(liste)
	word = liste[current_pos]
	while current_pos <= list_length:
		if current_pos < list_length:
			new_word = liste[current_pos]
			if word != new_word:
				last_pos = current_pos - 1
				anzahl_vorkommen = last_pos - first_pos
				out_liste.insert(0, word)
				nr_liste.insert(0, [word, anzahl_vorkommen + 1])
				first_pos = current_pos
				word = liste[current_pos]
		else:
			last_pos = current_pos - 1
			anzahl_vorkommen = last_pos - first_pos
			out_liste.insert(0, word)
			nr_liste.insert(0, [word, anzahl_vorkommen + 1])
		current_pos = current_pos + 1
	out_liste.reverse()
	nr_liste.reverse()
	return out_liste, nr_liste, list_length
Edit by Dookie: Code in Pythontags gesetzt
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

hier mal meine Version, unter Einbeziehung vorhandener Lösungen.

Code: Alles auswählen

def count_words2(liste):
    out_liste = [item for (i,item) in enumerate(liste) if item not in liste[:i]]
    nr_liste = [[item, liste.count(item)] for item in out_liste]
    list_length = len(liste)
    return out_liste, nr_liste, list_length
Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
joe

Auch wenn ich nicht ganz verstaqnden habe, was cpythons count_words leisten soll:

Code: Alles auswählen

def count_words3(liste):
    wc = {}
    for w in liste:
        wc[w] = 1 + wc.get(w,0)
    return wc.keys(),wc.items(),len(liste)
Das resultat ist zumindest sehr ähnlich.
joe
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

ich hab auch noch eine Alternative, diesmal mit Set.

Code: Alles auswählen

from sets import Set # für Pythonversion < 2.4

def count_words3(liste):
    nr_liste = [[item, liste.count(item)] for item in Set(liste)]
    out_liste = [item for item, nr in nr_liste]
    list_length = sum([nr for item, nr in nr_liste])
    return out_liste, nr_liste, list_length
Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Antworten