2013-04-26 4 views
0

Я пытаюсь добавить элементы из списка списков в набор. Например, если бы я былДобавление элементов из списка списков в набор?

new_list=[['blue','purple'],['black','orange','red'],['green']] 

Как бы я получить

new_set=(['blue','purple'],['black','orange','red'],['green']) 

Я пытаюсь сделать это так, что я могу использовать перекресток, чтобы выяснить, какие появляются элементы в 2-х комплектов. Я думал, что это будет работать ...

results=set() 
results2=set() 
for element in new_list: 
    results.add(element) 

for element in new_list2: 
    results2.add(element) 
results3=results.intersection(results2) 

но я продолжаю прием:

TypeError: unhashable type: 'list' 

по какой-то причине.

ответ

4

Преобразовать внутренние списки кортежей, так как наборы позволяют хранить только hashable (неизменяемый) объектов:

In [72]: new_list=[['blue','purple'],['black','orange','red'],['green']] 

In [73]: set(tuple(x) for x in new_list) 
Out[73]: set([('blue', 'purple'), ('black', 'orange', 'red'), ('green',)]) 
3

Как бы я получить

new_set=(['blue','purple'],['black','orange','red'],['green']) 

Ну, несмотря на то, вводящее в заблуждение имя, это не set ничего, это tuple от list s. Для преобразования list из list с в tuple из list с:

new_set = tuple(new_list) 

Может быть, вы хотели бы получить это?

new_set=set([['blue','purple'],['black','orange','red'],['green']]) 

Если так ... вы не можете. A set не может содержать нечувствительные значения, такие как list. Вот что вам говорит TypeError.

Если бы это было не проблема, все, что вам придется сделать, это написать:

new_set = set(new_list) 

И ничего более сложно писать будет точно такая же проблема, как просто вызов set, так что нет сложно вокруг него.


Конечно, вы можете иметь set из tuple с, так как они hashable. Так, возможно, вы хотели этого:

new_set=set([('blue','purple'),('black','orange','red'),('green')]) 

Это тоже легко. Предполагая, что ваши внутренние list S гарантированно не содержат ничего, кроме строк (или других hashable значений), так как в вашем примере это просто:

new_set = set(map(tuple, new_list)) 

Или, если вы используете сортировки на основе набора класс, вы не Не нужны хешируемые значения, просто полностью упорядоченные значения.Например:

new_set = sortedset(new_list) 

Python не приходит с такой вещью в стандартной библиотеке, но есть некоторые большие реализации сторонних вы можете установить, как blist.sortedset или bintrees.FastRBTree.

Конечно, операции сортировки не такие быстрые, как операции хэша в целом, но часто они более чем достаточно хороши. (Для конкретного примера, если у вас есть 1 миллион элементов в списке, хэширования будет делать каждый поиск 1 миллион раз быстрее,. Сортировка будет только сделать это в 50000 раз быстрее)


В принципе, любой выход можно описать или привести пример, мы можем рассказать вам, как получить это, или что это не действительный объект, который вы можете получить ... но сначала вы должны сказать нам, что вы на самом деле хотите.


Кстати, если вам интересно, почему list s не hashable, это просто потому, что они изменяемые. Если вам интересно, почему большинство изменчивых типов не хешируются, это объясняет the FAQ.

1

сделать элемент кортежа перед добавлением его в комплекте:

new_list=[['blue','purple'],['black','orange','red'],['green']] 
new_list2=[['blue','purple'],['black','green','red'],['orange']] 

results=set() 
results2=set() 
for element in new_list: 
    results.add(tuple(element)) 

for element in new_list2: 
    results2.add(tuple(element)) 

results3=results.intersection(results2) 
print results3 

приводит:

set([('blue', 'purple')]) 

Установить элементы должны быть hashable.

  • для добавления списков к набору, вместо этого использовать кортеж
  • для добавления набора к набору, вместо того, чтобы использовать frozenset
Смежные вопросы