2012-06-17 9 views
6

Powiedz, że mam zestaw myset obiektów niestandardowych, które mogą być równe, chociaż ich odwołania są różne (a == b and a is not b). Teraz jeśli I add(a) do zestawu, Python poprawnie zakłada, że ​​a in myset and b in myset, mimo że jest tylko obiekt len(myset) == 1 w zestawie.Python: Uzyskaj dostęp do elementów zestawu

To jasne. Ale czy teraz jest możliwe wyodrębnienie wartości a z zestawu, używając tylko b? Załóżmy, że obiekty są zmienne i chcę je zmienić, zapominając o bezpośrednim odnośniku do a. Inaczej mówiąc, szukam operacji myset[b], która zwróci dokładnie element członkowski a zestawu.

Wydaje mi się, że typ set nie może tego zrobić (szybciej niż iterowanie przez wszystkie jego elementy). Jeśli tak, czy istnieje przynajmniej skuteczne obejście?

+0

Dlaczego trzeba to zrobić? Jeśli masz już 'b', dlaczego potrzebujesz' a', który jest równy? –

+0

To jedno wymaganie fugly ... –

+0

@KarlKnechtel: element wewnątrz zestawu jest przywoływany gdzie indziej (z wnętrza głębokiej struktury) i chcę zmienić jego wartość. Obiekty są w zasadzie typu wektorowego 2D i są zmienne. – emu

Odpowiedz

5

Nie sądzę, że set obsługuje pobieranie elementu w czasie O (1), ale zamiast tego można użyć wartości dict.

d = {} 
d[a] = a 
retrieved_a = d[b] 
+0

Właściwie to oprzyrządowałem z tym i spojrzałem na źródło jakiś czas temu, a IIRC, cpython zawsze iteruje nad mniejszym zestawem szukając skrzyżowań. Więc co masz działa, ale jeśli 's' jest dłuższy, to zwróci' b'. – senderle

+0

@senderle: Myślę, że masz rację - [źródło zestawu] (http://svn.python.org/projects/python/trunk/Objects/setobject.c).Wtedy moje drugie podejście kończy się niepowodzeniem, więc je usuwam. Dziękuję za wskazanie. –

0

Jeśli masz tylko myset i b, to z tej perspektywy, nie będzie mieć dostępu do a bo go tam nie ma. Jeśli utworzysz wiele zmiennoprzecinkowych obiektów i dodasz jedną z nich do myset, pozostałe nie są "znane", gdy masz do czynienia tylko z myset lub dodanym obiektem. Jeśli chcesz zmodyfikować a i , musisz śledzić gdziekolwiek oba obiekty

0

Może to:

(myset - (myset - set([b]))).pop() is a 
+0

Działa, ale ustawiona różnica (a mianowicie pierwsza) najprawdopodobniej wymaga, aby Python usuwał wszystkie elementy jeden po drugim. Z tego powodu jest asymptotycznie tak samo powolny jak iteracja przez zestaw. – emu

+0

@emu: może, chociaż przypuszczam, że mogą być pewne optymalizacje dla przypadków krawędziowych. Tak czy inaczej, obawiam się, że jest to jedyny sposób korzystania z zestawów _only_, bez uciekania się do dyktowania lub wyszukiwania liniowego. – georg