Thêm danh sách để thiết lập?


242

Đã thử nghiệm trên trình thông dịch Python 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

Tôi nghĩ rằng tôi không thể thêm danh sách vào tập hợp vì không có cách nào Python có thể nói Nếu tôi đã thêm cùng một danh sách hai lần. Có một cách giải quyết?

EDIT: Tôi muốn thêm danh sách chính nó, không phải các yếu tố của nó.


2
Bạn có muốn thêm danh sách vào tập hợp hoặc các mục trong danh sách không?
pkit

Bản thân danh sách - Tôi muốn có một bộ danh sách.
Adam Matan

Có vẻ như câu trả lời phù hợp nhất là câu trả lời bị đánh giá thấp, đề xuất sử dụng a Set.add (id (lst)) trước khi thêm lst vào danh sách / hàng đợi / vv, để chắc chắn rằng bạn đã thực hiện nó. Bạn nên xem xét lại câu trả lời được chấp nhận.
Rustam A.

Câu trả lời:


187

Bạn không thể thêm danh sách vào tập hợp vì danh sách có thể thay đổi, nghĩa là bạn có thể thay đổi nội dung của danh sách sau khi thêm danh sách vào tập hợp.

Tuy nhiên, bạn có thể thêm bộ dữ liệu vào bộ vì bạn không thể thay đổi nội dung của bộ dữ liệu:

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

Chỉnh sửa : một số giải thích: Các tài liệu định nghĩa một setnhư một bộ sưu tập có thứ tự của các đối tượng hashable riêng biệt. Các đối tượng phải được băm để việc tìm, thêm và xóa các phần tử có thể được thực hiện nhanh hơn so với việc xem xét từng phần tử riêng lẻ mỗi khi bạn thực hiện các thao tác này. Các thuật toán cụ thể được sử dụng được giải thích trong bài viết Wikipedia . Các thuật toán băm của pythons được giải thích trên hàm effbot.org và pythons __hash__trong tham chiếu python .

Một số sự thật:

  • Đặt các yếu tố cũng như các khóa từ điển phải được băm
  • Một số kiểu dữ liệu không thể xóa được:
    • list: sử dụng tuplethay thế
    • set: sử dụng frozensetthay thế
    • dict: không có đối tác chính thức, nhưng có một số công thức nấu ăn
  • Các thể hiện đối tượng được băm theo mặc định với mỗi thể hiện có một hàm băm duy nhất. Bạn có thể ghi đè hành vi này như được giải thích trong tài liệu tham khảo python.

6
Và nếu bạn muốn thêm một bộ vào một bộ, hãy sử dụng froundredet.
FogleBird

4
collections.namedtuplecó thể được coi là đối tác "chính thức" của dict.
SilentGhost

1
@Wahnfrieden: đó là thêm nội dung của một bộ chứ không phải chính bộ đó.
Otto Allmendinger

@aehlke: Không, điều đó thêm các phần tử của tập hợp vào tập đầu tiên, nhưng chúng ta đang nói về việc thêm một tập hợp làm một phần tử của tập đầu tiên.
Jeff Learman

578

Sử dụng set.update()hoặc|=

>>> 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'}

chỉnh sửa: Nếu bạn muốn thêm danh sách đó chứ không phải thành viên của nó, thì bạn phải sử dụng một tuple, thật không may. Đặt thành viên phải được băm .


set.update () thêm danh sách vào tập hợp, đúng không? các nhà điều hành ống bằng là gì?
FistOfFury

Đối với các bộ, |toán tử thực hiện thao tác tập hợp . Cả |=toán tử và set.update()phương thức đều áp dụng thao tác đó tại chỗ và đồng nghĩa một cách hiệu quả. Vì vậy, set_a |= set_bcó thể được coi là đường cú pháp cho cả hai set_a.update(set_b) set_a = set_a | set_b (ngoại trừ trong trường hợp sau, cùng một set_ađối tượng được sử dụng lại thay vì gán lại). </ahem>
Cecil Curry

76

Để thêm các yếu tố của một danh sách vào một bộ , sử dụngupdate

Từ https://docs.python.org/2/l Library / sets.html

s.update (t): return set s với các phần tử được thêm từ t

Ví dụ

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

Thay vào đó, nếu bạn muốn thêm toàn bộ danh sách dưới dạng một thành phần vào tập hợp, bạn không thể vì danh sách không thể băm được. Thay vào đó, bạn có thể thêm một tuple, vd s.add(tuple(l)). Xem thêm TypeError: loại không thể xóa: 'list' khi sử dụng chức năng thiết lập sẵn để biết thêm thông tin về điều đó.


40

Hy vọng điều này sẽ giúp:

>>> 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'])

15

Xin hãy chú ý chức năng set.update(). Các tài liệu nói:

Cập nhật một bộ với sự kết hợp của chính nó và những người khác.


5
Điều này không trả lời câu hỏi (vì OP muốn tự thêm danh sách vào tập hợp) nhưng đó là câu trả lời tôi cần khi Google đưa tôi đến đây :-)
tom stratton 26/03/13

1
Chà, có vẻ như câu trả lời phù hợp nhất cho câu hỏi đối với tôi ... chẳng hạn, nếu b = set ([1]), b.update ([7,25]) sẽ cho b giá trị sau: set ([ 1, 25, 7]) ---> Không phải đó là những gì chúng ta đang tìm kiếm ở đây sao?
Louis LC

8

danh sách các đối tượng là không thể . bạn có thể muốn biến chúng thành bộ dữ liệu mặc dù.


5

Các bộ không thể có các thành phần / thành viên có thể thay đổi (có thể thay đổi). Một danh sách, có thể thay đổi, không thể là thành viên của một tập hợp.

Vì các bộ có thể thay đổi, bạn không thể có một bộ! Bạn có thể có một bộ froundredets mặc dù.

(Loại "yêu cầu về tính biến đổi" tương tự áp dụng cho các khóa của một lệnh.)

Các câu trả lời khác đã cung cấp cho bạn mã, tôi hy vọng điều này cung cấp một chút cái nhìn sâu sắc. Tôi hy vọng Alex Martelli sẽ trả lời với nhiều chi tiết hơn nữa.


4

Bạn muốn thêm một tuple, không phải danh sách:

>>> 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')])

Nếu bạn có một danh sách, bạn có thể chuyển đổi sang bộ dữ liệu, như được hiển thị ở trên. Một tuple là bất biến, vì vậy nó có thể được thêm vào tập hợp.


4

Tôi thấy tôi cần phải làm một cái gì đó tương tự ngày hôm nay. Thuật toán biết khi nào nó tạo ra một danh sách mới cần thêm vào tập hợp, nhưng không phải khi nào nó sẽ hoàn thành hoạt động trong danh sách.

Dù sao, hành vi tôi muốn là để thiết lập để sử dụng idchứ không phải hash. Như vậy tôi tìm thấy mydict[id(mylist)] = mylistthay vì myset.add(mylist)đưa ra hành vi tôi muốn.


3

Bạn sẽ muốn sử dụng các bộ dữ liệu có thể băm (bạn không thể băm một đối tượng có thể thay đổi như danh sách).

>>> 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')])

2

Đây là cách tôi thường làm:

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

-4

Điều này nên làm:

set(tuple(i) for i in L)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.