2010-10-28 10 views

Odpowiedz

154

przez zestaw, masz na myśli set?

>>> foo = set(range(0, 4)) 
>>> foo 
set([0, 1, 2, 3]) 
>>> foo.update(range(2, 6)) 
>>> foo 
set([0, 1, 2, 3, 4, 5]) 
+3

Tak, nie spodziewałem się, że będzie dwuznaczny, ale wygląda na to, że jest :) Aktualizacja jest rzeczą bardzo ważną. Dziękuję Ci! –

+2

Spojrzałem tylko na moją sesję tłumacza i faktycznie wypróbowałem to, ale pomyślałem, że dodało ono całą listę jako element zestawu z powodu nawiasów kwadratowych w reprezentacji zestawu. Nigdy wcześniej nie zauważyłem, że są reprezentowani w ten sposób. –

+6

Ta reprezentacja umożliwia wklejenie jej z powrotem w sesji interaktywnej, ponieważ konstruktor 'set' przyjmuje jako argument iterację. –

-4

Kocham ten sposób:

set = [item for item in items] 
+0

@dolma, nie chcę, aby utworzyć * * nowy zestaw, ale dodać do zachowany zestaw. Przepraszam, jeśli to było niejasne; Zmieniłem to pytanie, by wyjaśnić. –

+0

@dolma, również, (a) możesz zrobić 's = set (items)' oraz (b) twój przykład na nowo definiuje wbudowany :) –

+0

to po prostu możesz zrobić 'set.extend ([element dla pozycji w pozycjach ]) ', Myślę ... – dolma33

-1

Zastosowanie lista zrozumieniem.

Krótkie spięcie tworzenie iterable używając listę na przykład :)

>>> x = [1, 2, 3, 4] 
>>> 
>>> k = x.__iter__() 
>>> k 
<listiterator object at 0x100517490> 
>>> l = [y for y in k] 
>>> l 
[1, 2, 3, 4] 
>>> 
>>> z = Set([1,2]) 
>>> z.update(l) 
>>> z 
set([1, 2, 3, 4]) 
>>> 

[EDIT: brakowało nastawioną część Pytanie]

+1

Nie widzę żadnych zestawów? Czy czegoś brakuje? –

+1

@Ian Mackinnon: Aah! Zupełnie tęskniłem za tym punktem. Dzięki. – pyfunc

-1
for item in items: 
    extant_set.add(item) 

Dla przypomnienia, myślę, że twierdzenie, że „nie powinno być jedno- i korzystnie tylko jeden --obvious sposób to zrobić.” jest fałszywe. Przyjmuje założenie, że wielu myślących technicznie ludzi sprawia, że ​​wszyscy myślą tak samo. To, co dla jednej osoby jest oczywiste, nie jest tak oczywiste dla drugiego.

Chciałbym argumentować, że proponowane przeze mnie rozwiązanie jest czytelne i spełnia to, o co prosisz. Nie wierzę, że są w to zaangażowane jakieś hity wydajności - choć przyznaję, że czegoś mi brakowało. Ale mimo wszystko, może nie być oczywiste i lepsze od innego programisty.

+0

Argh! Pętla for znajdująca się w jednym wierszu to formatowanie w mojej odpowiedzi - nigdy bym tego nie zrobił. Zawsze. – jaydel

+1

używają 'add' nie' append' – FogleBird

+0

Jesteś absolutnie poprawny. Edytowałem post, aby naprawić moje obrażenia. Dzięki :) – jaydel

0

Zestawy posiadają metodę dodawać zbyt:

>>> s=set([1,2,3,4]) 
>>> for n in range(10): 
     s.add(n) 
>>> s 
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
7

można użyć funkcji set() do konwersji iterable w zestawie, a następnie użyć standardowego operatora zestaw aktualizacji (| =), aby dodać unikatowe wartości od nowego zestawu do istniejącego.

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

Użycie '.update' ma tę zaletę, że argumentem może być dowolna iteracja - niekoniecznie jest to zestaw podobny do RHS operatora' | = 'w twoim przykładzie. – tzot

+1

Dobra uwaga. To po prostu estetyczny wybór, ponieważ set() może przekonwertować plik iterowalny na zestaw, ale liczba naciśnięć klawiszy jest taka sama. – gbc

+0

Nigdy wcześniej nie widziałem tego operatora, z przyjemnością go użyję, gdy pojawi się w przyszłości; dzięki! – eipxen

30

Dla korzyści każdego, kto może wierzyć np. że robi aset.add() w pętli miałby wydajność konkurencyjnej robi aset.update(), oto przykład jak można przetestować swoje przekonania szybko przed upublicznieniem:

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a.update(it)" 
1000 loops, best of 3: 294 usec per loop 

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "for i in it:a.add(i)" 
1000 loops, best of 3: 950 usec per loop 

>\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a |= set(it)" 
1000 loops, best of 3: 458 usec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a.update(it)" 
1000 loops, best of 3: 598 usec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "for i in it:a.add(i)" 
1000 loops, best of 3: 1.89 msec per loop 

>\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a |= set(it)" 
1000 loops, best of 3: 891 usec per loop 

Wygląda kosztów za przesyłkę podejścia pętli jest ponad trzykrotnie z podejścia update.

Używanie |= set() kosztuje około 1,5x to, co robi update, ale połowę tego, co dodaje każdy pojedynczy element w pętli.

0

Tylko szybka zmiana, czasy przy użyciu Pythona 3:

#!/usr/local/bin python3 
from timeit import Timer 

a = set(range(1, 100000)) 
b = list(range(50000, 150000)) 

def one_by_one(s, l): 
    for i in l: 
     s.add(i)  

def cast_to_list_and_back(s, l): 
    s = set(list(s) + l) 

def update_set(s,l): 
    s.update(l) 

Wyniki są następujące:

one_by_one 10.184448844986036 
cast_to_list_and_back 7.969255169969983 
update_set 2.212590195937082 
Powiązane problemy