Python entfernen Set aus Set


74

Gemäß meiner Interpretation der Python 2.7.2-Dokumentation für integrierte Typen 5.7 Set-Typen sollte es möglich sein, die Elemente von Set A aus Set B zu entfernen, indem A an set.remove(elem)oder übergeben wirdset.discard(elem)

Aus der Dokumentation zu 2.7.2:

Beachten Sie , dass das Elem Argument der __contains__(), remove()und discard() Methoden kann ein Satz sein.

Ich interpretiere dies so, dass ich ein setan remove(elem)oder übergeben kann discard(elem)und alle diese Elemente aus dem Zielsatz entfernt werden. Ich würde dies verwenden, um etwas Seltsames zu tun, wie alle Vokale aus einer Zeichenfolge zu entfernen oder alle gebräuchlichen Wörter aus einem Worthäufigkeitshistogramm zu entfernen . Hier ist der Testcode:

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [M...
Type "help", "copyright", "credits" or "license"
>>> a = set(range(10))
>>> b = set(range(5,10))
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
set([8, 9, 5, 6, 7])
>>> a.remove(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: set([8, 9, 5, 6, 7])
>>> a.discard(b)
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>

Was ich voraussichtlich wiederkommen werde:

>>> a
set([0, 1, 2, 3, 4])

Ich weiß, dass ich dies erreichen kann, a.difference(b)wodurch ein neuer Satz zurückgegeben wird. oder mit einem set.difference_update(other); oder mit Set-Operatoren a -= b, die das Set an Ort und Stelle ändern.

Ist das also ein Fehler in der Dokumentation? Kann man set.remove(elem)eigentlich keinen Satz als Argument nehmen? Oder bezieht sich die Dokumentation auf Sätze von Sätzen? Angesichts der Tatsache, dass difference_updatedies meine Interpretation erfüllt, ist der Fall vermutlich der letztere.

Ist das unklar genug?

BEARBEITEN Nach 3 Jahren zusätzlicher (professioneller) Python-Arbeit und nachdem ich kürzlich auf diese Frage zurückgegriffen habe, stelle ich jetzt fest, dass das, was ich eigentlich versucht habe, erreicht werden kann mit:

>>> c = a.difference(b)
set([0,1,2,3,4])

Das ist es, was ich ursprünglich versucht habe zu bekommen.

BEARBEITEN Nach 4 weiteren Jahren Python-Entwicklung ... ist mir klar, dass diese Operation mit festgelegten Literalen und dem -Operator sauberer ausgedrückt werden kann . und dass es vollständiger ist zu zeigen, dass die eingestellte Differenz nicht kommutativ ist.

>>> a={0,1,2,3}
>>> b={2,3,4,5}
>>> a-b
set([0, 1])
>>> b-a
set([4, 5])

c = a.difference(b)funktioniert bei mir. Vielen Dank!
Gihanchanuka

Antworten:


21

Sie haben die Frage bereits beantwortet. Es bezieht sich auf Sätze von Sätzen (tatsächlich Sätze, die Frozensets enthalten).

Der Absatz, auf den Sie sich beziehen, beginnt mit:

Beachten Sie, dass das Argument elem für die Methoden __contains __ (), remove () und discard () eine Menge sein kann.

was bedeutet, dass bin a.remove(b)eine Menge sein kann und dann fortfährt mit:

Um die Suche nach einem äquivalenten Frozenset zu unterstützen , wird das Element-Set während der Suche vorübergehend mutiert und dann wiederhergestellt. Während der Suche sollte das Element-Set nicht gelesen oder mutiert werden, da es keinen aussagekräftigen Wert hat.

Das bedeutet , dass , wenn bein Satz ist, a.remove(b)scannt aeine frozenset entspricht bund abnehmen (oder einen Wurf , KeyErrorwenn es nicht vorhanden ist).


Vielen Dank! Angesichts meiner Fehlinterpretation ergab dieser zweite Satz wenig Sinn. Dies als primäre Antwort zu wählen, da es hilft, mein primäres Missverständnis zu klären. Lings Beispiel war auch sehr hilfreich.
cod3monk3y


8

Sie können in Python kein sets von sets haben, da a setveränderlich ist. Stattdessen können Sie sets von frozensets haben. Auf der anderen Seite, können Sie anrufen __contains__(), remove()und discard()mit ein set. Siehe dieses Beispiel:

a = set([frozenset([2])])
set([2]) in a       # you get True
a.remove(set([2]))  # a is now empty

Die Antwort auf Ihre Frage lautet also, dass sich die Dokumentation auf sets von frozensets bezieht .


Sehr schöne, prägnante Darstellung dessen, was für mich ein ungewöhnlich unklarer Teil der Python-Dokumentation ist. Danke Ling!
cod3monk3y

2

Ich schaue mir die eingebaute Hilfe für verschiedene Versionen von Python (für Mac) an. Hier sind die Ergebnisse.

  • python2.5

entfernen (...)
Ein Element aus einer Menge entfernen; es muss ein Mitglied sein.
Wenn das Element kein Mitglied ist, lösen Sie einen KeyError aus.

  • python2.6

entfernen (...)
Ein Element aus einer Menge entfernen; es muss ein Mitglied sein. Wenn das Element kein Mitglied ist, lösen Sie einen KeyError aus.

  • python2.7

entfernen (...)
Ein Element aus einer Menge entfernen; es muss ein Mitglied sein. Wenn das Element kein Mitglied ist, lösen Sie einen KeyError aus.

In der Dokumentation, auf die Sie sich vollständig beziehen, heißt es tatsächlich:

Beachten Sie , dass das Elem Argument der __contains__(), remove()und discard()Methoden kann ein Satz sein. Um die Suche nach einem äquivalenten Frozenset zu unterstützen, wird das Element-Set während der Suche vorübergehend mutiert und dann wiederhergestellt.

Dies scheint eine Fußnote zu sein, die darauf hindeutet, dass das Argument eine Menge sein kann. Wenn es jedoch keine passende eingefrorene Menge innerhalb der Menge findet, wird es nicht entfernt. Die Erwähnung über das zu ändernde Set ist so, dass es gehasht werden kann, um nach einem passenden eingefrorenen Set zu suchen.


1

Ich denke, die Dokumentation bezieht sich auf Sätze von (eingefrorenen) Sätzen, ja.


2
Aber Sie können keine Sätze haben; Sets sind nicht hashbar. Sie könnten ein Set mit einem Frozenset als Element haben, denke ich.
DSM

2
@DSM - daher wird in der Dokumentation der elemWert erwähnt, der während des Aufrufs mutiert wird, um festzustellen , ob es ein Äquivalent gibt frozenset.
Amber
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.