2009-08-20 22 views
141

Thử nghiệm trên Python 2.6 phiên dịch:Python: Thêm danh sách để đặt?

>>> 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 để các thiết lậ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ó cách giải quyết nào không?

CHỈNH SỬA: Tôi muốn thêm chính danh sách, chứ không phải các thành phần của danh sách.

+2

Bạn có muốn thêm danh sách để thiết lập hoặc các mục trong danh sách? – pkit

+0

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

+0

Sau đó, sử dụng tùy chọn tuple mà Otto đã trả lời. – pkit

Trả lời

131

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

Bạn tuy nhiên có thể thêm các bộ để thiết lập, bởi vì bạn không thể thay đổi nội dung của một tuple:

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

Sửa: một số giải thích: Các tài liệu định nghĩa một set như một bộ sưu tập có thứ tự của các đối tượng có thể băm riêng biệt. Các đối tượng phải được băm để tìm kiếm, thêm và loại bỏ các phần tử có thể được thực hiện nhanh hơn so với xem từng phần tử riêng lẻ mỗi lần 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 Wikipedia article. Thuật toán băm Pythons được giải thích trên effbot.org và pythons __hash__ chức năng trong python reference.

Một số thông tin:

  • Set yếu tố cũng như phím từ điển phải hashable
  • Một số kiểu dữ liệu unhashable:
    • list: sử dụng tuple thay
    • set: sử dụng frozenset thay vì
    • dict: không có đối tác chính thức, nhưng có một số recipes
  • trường hợp đối tượng được hashable theo mặc định với mỗi trường hợp có một băm độc đáo. Bạn có thể ghi đè hành vi này như được giải thích trong tham chiếu python.
+4

Và nếu bạn muốn thêm một bộ vào tập hợp, hãy sử dụng frozenset. – FogleBird

+4

['collections.namedtuple'] (http://docs.python.org/library/collections.html#collections.namedtuple) có thể được coi là đối tác" chính thức "của' dict'. – SilentGhost

+2

@FogleBird hoặc toán tử liên kết: | = – aehlke

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

Toán tử kết hợp nhanh hơn nhiều so với cách thêm.

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

+20

'a.update (l)' có cùng tác dụng. –

8

đối tượng danh sách không thể sửa được. bạn có thể muốn biến chúng thành tuples.

3

Bạn sẽ muốn sử dụng bộ dữ liệu, có thể băm (bạn không thể băm một đối tượng có thể thay đổi giống 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')]) 
+0

Wow, chúng tôi đã viết gần như chính xác cùng một điều cùng một lúc. – hughdbrown

4

Bạn muốn thêm một tuple, không phải là một 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 các tuple, như trình bày ở trên. Một tuple là không thay đổi, vì vậy nó có thể được thêm vào bộ này.

+0

bạn không cần 'tuple (x cho x trong l)', bạn chỉ có thể làm: 'tuple (l)' – SilentGhost

+0

Ah, phải. Tôi có cú pháp hiểu danh sách bị kẹt trong các ngón tay của tôi. – hughdbrown

4

Bộ không thể có thành phần/thành phần có thể thay đổi (có thể thay đổi). Danh sách, có thể thay đổi, không thể là thành viên của nhóm.

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

(Cùng một loại "yêu cầu mutability" áp dụng cho các phím của một dict.)

câu trả lời khác đã đưa cho bạn mã, tôi hy vọng điều này sẽ cho mộ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.

2

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

Dù sao, hành vi tôi muốn được đặt để sử dụng id thay vì hash. Như vậy tôi đã tìm thấy mydict[id(mylist)] = mylist thay vì myset.add(mylist) để cung cấp hành vi mà tôi muốn.

13

Hãy lưu ý chức năng set.update(). Tài liệu hướng dẫn cho biết:

Cập nhật tập hợp 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 thêm danh sách chính nó vào bộ này) nhưng đó là câu trả lời tôi cần khi Google đưa tôi tới đây :-) –

+1

Vâng, có vẻ như câu trả lời phù hợp nhất với câu hỏi với tôi ... ví dụ, 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 tôi đang tìm kiếm ở đây? –

37

Hy vọng rằng đâ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']) 
3

Sau đây là cách tôi thường làm điều đó:

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

Để thêm các yếu tố của một danh sách để một bộ, sử dụng update

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

s.update (t): return bộ s với các yếu tố bổ sung từ t

Ví dụ:

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

Nếu bạn thay vì muốn thêm toàn bộ danh sách như một yếu tố duy nhất vào tập, bạn có thể không phải vì danh sách không hashable. Thay vào đó, bạn có thể thêm một bộ dữ liệu, ví dụ: s.add(tuple(l)). Xem thêm TypeError: unhashable type: 'list' when using built-in set function để biết thêm thông tin về điều đó.

-1

này nên làm:

set(tuple(i) for i in L) 
Các vấn đề liên quan