2009-08-20 14 views
141

Testowane na Pythona 2.6 tłumacza:Python: Dodaj listę do ustawienia?

>>> a=set('abcde') 
>>> a 
set(['a', 'c', 'b', 'e', 'd']) 
>>> l=['f','g'] 
>>> l 
['f', 'g'] 
>>> a.add(l) 
Traceback (most recent call last): 
    File "<pyshell#35>", line 1, in <module> 
    a.add(l) 
TypeError: list objects are unhashable 

myślę, że nie mogę dodać listę do zestawu, ponieważ nie ma sposobu, Python może powiedzieć, czy Dodałem tę samą listę dwukrotnie. Czy jest w pobliżu praca?

EDYCJA: Chcę dodać samą listę, a nie jej elementy.

+2

Chcesz dodać listę do zestawu lub elementów na liście? – pkit

+0

Sama lista - chcę mieć zestaw list. –

+0

Następnie użyj opcji krotki, na którą odpowiedział Otto. – pkit

Odpowiedz

131

Nie można dodać listy do zestawu, ponieważ listy są zmienne, co oznacza, że ​​można zmienić zawartość listy po dodaniu jej do zestawu.

Można jednak dodać krotki do zestawu, ponieważ nie można zmienić zawartość krotki:

>>> a.add(('f', 'g')) 
>>> print a 
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')]) 

Edit: pewne wyjaśnienie: Dokumentacja określa set jako nieuporządkowaną kolekcji odrębnych, mierzalnych obiektów. Obiekty muszą być nieosiągalne, aby znajdowanie, dodawanie i usuwanie elementów mogło odbywać się szybciej niż przeglądanie każdego elementu za każdym razem, gdy wykonujesz te operacje. Określone algorytmy są wyjaśnione w Wikipedia article. Algorytmy mieszania języka Python są objaśniane na effbot.org i pythons __hash__ funkcji w python reference.

Kilka faktów:

  • Zestaw elementów jak również klucze słownika muszą być hashable
  • Niektóre unhashable datatypes:
    • list: użyj tuple zamiast
    • set: użyj frozenset zamiast
    • dict: nie posiada oficjalnego odpowiednika, ale istnieją pewne recipes
  • instancje obiektu są hashable domyślnie z każda instancja ma unikalny hash. Możesz zmienić to zachowanie, jak wyjaśniono w odnośniku Pythona.
+4

Jeśli kiedykolwiek chcesz dodać zestaw do zestawu, użyj parametru zamrożonego. – FogleBird

+4

['collections.namedtuple'] (http://docs.python.org/library/collections.html#collections.namedtuple) może być uznany za" oficjalny "odpowiednik" dyktatu ". – SilentGhost

+2

@ FogleBird lub operator związku: | = – aehlke

332
>>> a = set('abcde') 
>>> l = ['f', 'g'] 
>>> a |= set(l) 
>>> a 
set(['a', 'c', 'b', 'e', 'd', 'g', 'f']) 

operator Unia jest znacznie szybsze niż dodać tak.

edytuj: Jeśli chcesz mieć samą listę, a nie jej członków, musisz użyć niestety krotki. Ustawione elementy muszą być nieosiągalne.

+20

'a.update (l)' ma taki sam efekt. –

8

obiekty listy są nieusuwalne. możesz jednak włączyć je do krotek.

3

Będziesz chciał użyć krotek, które są zgodne z hashami (nie można mieszać obiektów zmiennych, takich jak lista).

>>> a = set("abcde") 
>>> a 
set(['a', 'c', 'b', 'e', 'd']) 
>>> t = ('f', 'g') 
>>> a.add(t) 
>>> a 
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')]) 
+0

Wow, napisaliśmy prawie dokładnie to samo w tym samym czasie. – hughdbrown

4

Chcesz dodać krotki, a nie listę:

>>> a=set('abcde') 
>>> a 
set(['a', 'c', 'b', 'e', 'd']) 
>>> l=['f','g'] 
>>> l 
['f', 'g'] 
>>> t = tuple(l) 
>>> t 
('f', 'g') 
>>> a.add(t) 
>>> a 
set(['a', 'c', 'b', 'e', 'd', ('f', 'g')]) 

Jeśli masz listę, można konwertować do krotki, jak pokazano powyżej. Krotka jest niezmienna, więc można ją dodać do zestawu.

+0

nie potrzebujesz 'tuple (x dla xw l)', możesz po prostu zrobić: 'tuple (l)' – SilentGhost

+0

Ah, racja. W moich palcach mam składnię ze zrozumieniem listy. – hughdbrown

4

Zestawy nie mogą mieć zmienne/zmienne elementy/elementy. Lista, która może być zmienna, nie może być członkiem zbioru.

Ponieważ zestawy są zmienne, nie można mieć zestawu zestawów! Możesz jednak mieć zestaw frozensets.

(Ten sam rodzaj „wymóg zmienność” odnosi się do kluczy dict).

Inne odpowiedzi zostały już podane Ci kod, mam nadzieję, że to daje trochę wglądu. Mam nadzieję, że Alex Martelli odpowie jeszcze więcej szczegółów.

2

Znalazłem, że muszę dzisiaj zrobić coś podobnego. Algorytm wiedział, kiedy tworzył nową listę, która musiała zostać dodana do zestawu, ale nie wtedy, gdy zakończyłaby działanie na liście.

W każdym razie zachowanie, którego pragnąłem, było dla zestawu do używania id zamiast hash. W związku z tym znalazłem mydict[id(mylist)] = mylist zamiast myset.add(mylist), aby zaoferować zachowanie, które chciałem.

13

Proszę zauważyć funkcję set.update(). Dokumentacja mówi:

Zaktualizuj zestaw ze związkiem siebie i innych.

+5

To nie odpowiada na pytanie (ponieważ OP chce dodać samą listę do zestawu), ale była to odpowiedź, której potrzebowałem, gdy Google mnie tu przywiózł :-) –

+1

Cóż, wydaje się być najbardziej odpowiednią odpowiedzią na pytanie do mnie ... na przykład, jeśli b = ustawiony ([1]), b.update ([7,25]) daje b następującą wartość: set ([1, 25, 7]) ---> Czy tego tu nie szukamy? –

37

Mam nadzieję, że to pomaga:

>>> seta = set('1234') 
>>> listb = ['a','b','c'] 
>>> seta.union(listb) 
set(['a', 'c', 'b', '1', '3', '2', '4']) 
>>> seta 
set(['1', '3', '2', '4']) 
>>> seta = seta.union(listb) 
>>> seta 
set(['a', 'c', 'b', '1', '3', '2', '4']) 
3

Oto jak zwykle zrobić:

def add_list_to_set(my_list, my_set): 
    [my_set.add(each) for each in my_list] 
return my_set 
25

Aby dodać elementy listy do zestawu, użyj update

od https://docs.python.org/2/library/sets.html

s.update (t): powrót zbiór s elementy dodane z T

Np

>>> s = set([1, 2]) 
>>> l = [3, 4] 
>>> s.update(l) 
>>> s 
{1, 2, 3, 4} 

Jeśli zamiast tego chcesz dodać całą listę jako pojedynczy element do zestawu, nie można, ponieważ listy są nie hashable. Zamiast tego możesz dodać krotkę, np. s.add(tuple(l)). Zobacz także TypeError: unhashable type: 'list' when using built-in set function, aby uzyskać więcej informacji na ten temat.

-1

ten powinien zrobić:

set(tuple(i) for i in L) 
Powiązane problemy