Dodać listę do zestawu?

Testowane na interpreterze Pythona 2.6:

>>> 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ć Listy do zestawu, ponieważ Python nie jest w stanie stwierdzić, czy dodałem tę samą listę dwa razy. Czy istnieje jakieś obejście?

EDIT: chcę dodać samą listę, a nie jej elementy.

Author: Paulo Boaventura, 2009-08-20

12 answers

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żesz jednak dodać krotki do zestawu, ponieważ nie możesz zmienić zawartości krotki:

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

Edit : pewne wyjaśnienie: dokumentacja Definiuje set jako nieuporządkowany zbiór odrębnych obiektów hashowalnych. obiekty muszą być hashowalne, aby odnajdywanie, dodawanie i usuwanie elementów mogło być robi się to szybciej niż oglądanie poszczególnych elementów za każdym razem, gdy wykonujesz te operacje. Szczegółowe algorytmy są wyjaśnione w artykule Wikipedii . Algorytmy haszujące Pythona są wyjaśnione na effbot.org i funkcji Pythona __hash__ W referencji Pythona .

Niektóre fakty:

  • elementy zestawu jak również klucze słownikowe muszą być hashowalne
  • niektóre nieszablonowe typy danych:
    • list: użycie tuple zamiast
    • set: Użyj frozenset zamiast
    • dict: nie ma oficjalnego odpowiednika, ale są pewne przepisy
  • instancje obiektów są domyślnie hashowalne, przy czym każda instancja ma unikalny hash. Możesz nadpisać to zachowanie, jak wyjaśniono w referencji Pythona.
 223
Author: Otto Allmendinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:24

Użycie set.update() lub |=

>>> a = set('abc')
>>> l = ['d', 'e']
>>> a.update(l)
>>> a
{'e', 'b', 'c', 'd', 'a'}

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

Edit: jeśli chcesz dodać samą listę, a nie jej członków, musisz niestety użyć krotki. Elementy zestawu muszą być hashable .

 670
Author: aehlke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-17 02:05:39

Do Dodaj elementy listy do zbioru , użyj update

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

S. update (t): return set s z elementami dodanymi 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żesz, ponieważ listy nie są hashowalne. Możesz zamiast tego dodać krotkę, np. s.add(tuple(l)). Zobacz także TypeError: unhashable type:' list ' podczas używania wbudowanego zestawu function aby uzyskać więcej informacji na ten temat.

 87
Author: JDiMatteo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:49

Miejmy nadzieję, że to pomoże:

>>> 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'])
 44
Author: alvas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-23 09:24:30

Zwróć uwagę na funkcję set.update(). Dokumentacja mówi:

Update a set with the union of itself and others.

 16
Author: eggfly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-20 21:44:31

Obiekty listy są niehaszowalne . możesz jednak oddać je na krotki.

 9
Author: SilentGhost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 14:43:17

Zestawy nie mogą mieć mutowalnych (zmiennych) elementów / członków. Lista, będąc zmienna, nie może być członkiem zestawu.

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

(ten sam rodzaj "wymogu zmienności" stosuje się do kluczy dict.)

Inne odpowiedzi już dały Ci kod, mam nadzieję, że to da trochę wglądu. Mam nadzieję, że Alex Martelli odpowie jeszcze bardziej szczegółowo.

 5
Author: user135331,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 15:16:53

Stwierdziłem, że muszę dziś zrobić coś podobnego. Algorytm wiedział, kiedy tworzy nową listę, która musi zostać dodana do zestawu, ale nie kiedy skończy działać na liście.

W każdym razie, zachowanie, które chciałem było dla set używać id zamiast hash. Jako taki znalazłem mydict[id(mylist)] = mylist zamiast myset.add(mylist), aby zaoferować zachowanie, które chciałem.

 5
Author: Dunes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-23 17:33:48

Chcesz dodać krotkę, 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żesz przekonwertować na krotkę, jak pokazano powyżej. Krotka jest niezmienna, więc można ją dodać do zestawu.

 4
Author: hughdbrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 16:54:09

Będziesz chciał użyć krotek, które mogą być hashowalne(nie możesz hashować mutowalnego obiektu, takiego 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')])
 3
Author: Noah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 14:45:08

Oto jak zwykle to robię:

def add_list_to_set(my_list, my_set):
    [my_set.add(each) for each in my_list]
return my_set
 2
Author: kashif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 07:26:42

Spróbuj użyć * rozpakuj, jak poniżej:

>>> a=set('abcde')
>>> a
{'a', 'd', 'e', 'b', 'c'}
>>> l=['f','g']
>>> l
['f', 'g']
>>> {*l, *a}
{'a', 'd', 'e', 'f', 'b', 'g', 'c'}
>>> 

Wersja bez edytora:

a=set('abcde')
l=['f', 'g']
print({*l, *a})

Wyjście:

{'a', 'd', 'e', 'f', 'b', 'g', 'c'}
 1
Author: U11-Forward,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-27 01:39:27