2016-11-22 3 views
-1

Ich habe einige Liste von Daten, zum BeispielWas ist ein pythonischer Weg, ein Set zu schneiden?

some_data = [1, 2, 4, 1, 6, 23, 3, 56, 6, 2, 3, 5, 6, 32, 2, 12, 5, 3, 2] 

und ich möchte eindeutige Werte mit fester Länge erhalten (i do not care, die ich erhalten), und ich will es auch set Objekt sein.

Ich weiß, dass ich tun kann, set von some_data es dann list machen, schneiden Sie es und dann es wieder machen set.

set(list(set(some_data))[:5]) # don't look so friendly 

Ich verstehe, dass ich besser nicht aussehen __getitem__ Methode in set haben, die nicht die ganze Scheibe etwas möglich machen würde, aber wenn es ist es eine Chance zu machen?

Und ich verstehe vollständig, dass set ungeordnet ist. Es spielt also keine Rolle, welche Elemente in das endgültige set gelangen.

Mögliche Optionen zu verwenden:

  • ordered-set
  • dict mit None Werten:

    set(dict(map(lambda x: (x, None), some_data)).keys()[:2]) # not that great 
    
+0

Was ist der Zweck, dies zu tun? – jprockbelly

+0

Zweck, ein 'Objekt' mit fester Länge aus einer großen Liste von Daten zu erhalten. Und dann mit diesem Set arbeiten (prüfen, ob der Wert in diesem Set ist). –

Antwort

3

Sets sind iterable. Wenn Sie wirklich nicht interessieren, welche Elemente aus Ihrem Satz ausgewählt sind, können Sie itertools.islice verwenden, um einen Iterator zu erhalten, der eine bestimmte Anzahl von Elementen (je nachdem, welche in der Iterationsreihenfolge zuerst kommen) liefert. Übergeben Sie den Iterator zum set Konstruktor und Sie haben Ihre Untergruppe bekam ohne zusätzliche Listen mit:

import itertools 

some_data = [1, 2, 4, 1, 6, 23, 3, 56, 6, 2, 3, 5, 6, 32, 2, 12, 5, 3, 2] 
big_set = set(some_data) 
small_set = set(itertools.islice(big_set, 5)) 

Während das ist, was Sie gefragt haben, ich bin nicht sicher, ob Sie es wirklich verwenden sollten. Sets können in einer sehr deterministischen Reihenfolge durchlaufen. Wenn Ihre Daten häufig viele ähnliche Werte enthalten, können Sie jedes Mal eine sehr ähnliche Untermenge auswählen, wenn Sie dies tun. Dies ist besonders schlimm, wenn die Daten aus Integern bestehen (wie im Beispiel), die sich selbst hashen. Aufeinanderfolgende Ganzzahlen werden sehr häufig in der Reihenfolge angezeigt, wenn ein Satz iteriert wird. Mit dem obigen Code ist nur 32 in big_set (mit Python 3.5) außer Betrieb, so small_set ist {32, 1, 2, 3, 4}. Wenn Sie Ihren Daten 0 hinzugefügt haben, würden Sie fast immer mit {0, 1, 2, 3, 4} enden, auch wenn der Datensatz sehr umfangreich wurde, da diese Werte immer die ersten fünf Slots in der Hash-Tabelle des Sets ausfüllen.

Um solche deterministische Stichproben zu vermeiden, können Sie random.sampleas suggested by jprockbelly verwenden.

+0

Awesome, ich dachte an 'islice', aber dann wechselte ich zu' slice', was'__getitem__' erforderte, und vergaß 'islice'. Guter Punkt! –

2

Sie könnten den Satz

import random 
set(random.sample(my_set, 5)) 
01 abtasten

Dies hat den Vorteil werden Sie verschiedene Zahlen jedes Mal

+0

Ziemlich eine Option, aber müssen sie in 'set' konvertieren, ich muss etwas Zeit laufen, um zu verstehen, ob es schneller ist. –

+0

Guter Punkt, siehe bearbeiten – jprockbelly

+1

Eine Stichprobe zu nehmen ist nicht schneller als Slicing. Eines der ersten Dinge, die die 'random.sample'-Implementierung macht, ist das Kopieren ihres Arguments in eine Liste, wenn es sich um eine Menge handelte (dann wird von der Liste ein Muster genommen). Aber die Verwendung von "Sample" kann sich trotzdem lohnen. Es wird vermieden, immer die gleichen Werte in Ihrer Teilmenge zu erhalten (Sätze können in einer nicht zufälligen Reihenfolge durchlaufen, z. B. sind Sätze aufeinanderfolgender kleiner Ganzzahlen oft in der richtigen Reihenfolge). – Blckknght

1

erhalten Sie einen einfachen Satz Verständnis versuchen könnte:

some_data = [1, 2, 4, 1, 6, 23, 3, 56, 6, 2, 3, 5, 6, 32, 2, 12, 5, 3, 2] 
n = {x for i, x in enumerate(set(some_data)) if i < 5} 
print n 

Ausgang:

set([32, 1, 2, 3, 4])

Verwandte Themen