2015-03-04 13 views
37

Jaka jest różnica między operacji dodawania i aktualizacji w python, jeśli chcę tylko dodać pojedynczą wartość do zestawu.dodać vs aktualizacji w operacji zestawu w python

a = set() 
a.update([1]) #works 
a.add(1) #works 
a.update([1,2])#works 
a.add([1,2])#fails 

Czy ktoś może wyjaśnić, dlaczego tak się dzieje.

+1

Jakiej wersji Python używasz? Dla 'a.update (1)' oczekuję 'TypeError: 'int' object nie jest iterable', i dostałem go dla obu wersji próbowałem. –

+1

@ theheyeye, twoja zmiana zmieniła trochę pytanie –

+0

https://github.com/python/cpython/blob/master/Objects/setobject.c – satomacoto

Odpowiedz

55

set.add

set.add dodaje indywidualny element do zestawu. Tak więc, działa, ale nie działa z wartością iterowalną, chyba że jest nieszyfrowany. To jest powód, dla którego a.add([1, 2]) zawodzi.

>>> a.add([1, 2]) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
TypeError: unhashable type: 'list' 

Tutaj [1, 2] jest traktowany jako element jest dodany do zestawu i jak mówi komunikat o błędzie, a list cannot be hashed ale oczekuje się, że wszystkie elementy zestawu być hashables. Cytowanie documentation,

Return a new set or frozenset object whose elements are taken from iterable. The elements of a set must be hashable .

set.update

W przypadku set.update można przekazać wiele iterables do niego i będzie iteracyjne wszystkie iterables i będzie obejmować poszczególne elementy w zestawie. Pamiętaj: Może przyjmować tylko iterables. Dlatego otrzymujesz błąd podczas próby aktualizacji ją 1

>>> a.update(1) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
TypeError: 'int' object is not iterable 

Ale dodaje będzie działać, ponieważ lista [1] się powtórzyć i elementy listy są dodawane do zestawu.

>>> a.update([1]) 
>>> a 
set([1]) 

set.update jest w zasadzie odpowiednikiem operacji połączenia zestawu w miejscu. Rozważmy następujące przypadki:

>>> set([1, 2]) | set([3, 4]) | set([1, 3]) 
set([1, 2, 3, 4]) 
>>> set([1, 2]) | set(range(3, 5)) | set(i for i in range(1, 5) if i % 2 == 1) 
set([1, 2, 3, 4]) 

Tutaj jawnie konwertujemy wszystkie iterables na sety, a następnie znajdujemy związek. Istnieje wiele pośrednich zestawów i związków. W tym przypadku set.update służy jako dobra funkcja pomocnika. Ponieważ przyjmuje żadnych iterable, można po prostu zrobić

>>> a.update([1, 2], range(3, 5), (i for i in range(1, 5) if i % 2 == 1)) 
>>> a 
set([1, 2, 3, 4]) 
+0

Jeśli chcesz zaktualizować my_set z zestawów w iteracji iterables, musisz użyć 'my_set.update (* [s for s in iterable])', przekazując generator tak jak w 'my_set .update (s dla s in iterable) 'zaktualizuje zestaw z elementami iterable i będzie dmuchać, jeśli te elementy nie będą się mieszać –

12

add jest szybsza dla pojedynczego elementu, ponieważ to właśnie w tym celu, dodając jeden element:

In [5]: timeit a.update([1]) 
10000000 loops, best of 3: 191 ns per loop 

In [6]: timeit a.add(1) 
10000000 loops, best of 3: 69.9 ns per loop 

update oczekuje iterable lub iterables więc jeśli masz pojedynczy hashable elementu do dodania następnie użyć add jeśli masz elementy iterowalne lub iterables z elementami podlegającymi skróceniu, dodaj adres: update.

s.add(x) add element x to set s

s.update(t) s |= t return set s with elements added from t

+0

Chociaż jest to prawdopodobnie oczywiste, należy zauważyć, że 'aktualizacja' jest znacznie szybsza w przypadku dodawania wielu elementów naraz:' timeit a.update (zakres (10000)) # => 1000 pętli, najlepiej 3: 431 μs loop', tymczasem 'timeit dla i w zakresie (10000): a.add (i) # => 1000 pętli, najlepiej z 3: 1,18 ms na pętlę' –

8

add dodaje element, update "zwiększa" inny iterowalny set, list lub tuple, na przykład:

In [2]: my_set = {1,2,3} 

In [3]: my_set.add(5) 

In [4]: my_set 
Out[4]: set([1, 2, 3, 5]) 

In [5]: my_set.update({6,7}) 

In [6]: my_set 
Out[6]: set([1, 2, 3, 5, 6, 7]) 
+0

Tylko uwaga, że ​​ta notacja jest dość aktualna. Python 2.7 i Python 3.1, zgodnie z http: // stackoverflow.com/a/31072911/1143274 –

3

.add() przeznaczony jest dla jednego element, a .update() jest wprowadzenie innych zestawy.

Od pomocy():

add(...) 
    Add an element to a set. 

    This has no effect if the element is already present. 


update(...) 
    Update a set with the union of itself and others. 
3

add akceptuje tylko typ hashable. Lista nie jest nieosiągalna.

2

a.update(1) w kodzie nie będą działać. add akceptuje element i umieszcza go w zestawie, jeśli jeszcze go tam nie ma, ale update dokonuje iteracji i tworzy związki zestawu z tym iterowalnym. To trochę tak, jak z listami: append i extend.

1

Wydaje mi się, że nikt nie wspomniał o dobrym źródle z Hackerrank. Chciałbym wkleić, jak Hackerrank wspomina o różnicy między aktualizacją i dodawaniem zestawu w pythonie.

Zestawy to torby nieuporządkowane o unikalnych wartościach. Pojedynczy zestaw zawiera wartości dowolnego niezmiennego typu danych.

TWORZENIE SET

myset = {1, 2} # Directly assigning values to a set 

myset = set() # Initializing a set 

myset = set(['a', 'b']) # Creating a set from a list 

print(myset) ===> {'a', 'b'} 

MODYFIKUJĄCE SET - add() i aktualizacja()

myset.add('c') 

myset ===>{'a', 'c', 'b'} 

myset.add('a') # As 'a' already exists in the set, nothing happens 

myset.add((5, 4)) 

print(myset) ===> {'a', 'c', 'b', (5, 4)} 


myset.update([1, 2, 3, 4]) # update() only works for iterable objects 

print(myset) ===> {'a', 1, 'c', 'b', 4, 2, (5, 4), 3} 

myset.update({1, 7, 8}) 

print(myset) ===>{'a', 1, 'c', 'b', 4, 7, 8, 2, (5, 4), 3} 

myset.update({1, 6}, [5, 13]) 

print(myset) ===> {'a', 1, 'c', 'b', 4, 5, 6, 7, 8, 2, (5, 4), 13, 3} 

Nadzieję, że to pomaga. Aby uzyskać więcej informacji na temat Hackerrank, here is the link.

Powiązane problemy