0

我正在尝试将列表中的元素添加到集合中。例如,如果我有

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

我将如何收到

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

我正在尝试这样做,这样我就可以使用交集来找出两组中出现的元素。我以为这会奏效...

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

3 回答 3

4

将内部列表转换为元组,因为集合允许您仅存储可散列(不可变)对象:

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',)])
于 2013-04-26T18:22:15.177 回答
3

我将如何收到

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

好吧,尽管名称具有误导性,但那不是set任何东西,那是tuples list。要将 a listof lists 转换为 a tupleof lists:

new_set = tuple(new_list)

也许你想收到这个?

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

如果是这样……你不能。Aset不能包含像lists 这样的不可散列值。这TypeError就是告诉你的。

如果这不是问题,您所要做的就是编写:

new_set = set(new_list)

你写的任何更复杂的东西都会遇到和 call 完全相同的问题set,所以没有什么棘手的方法可以绕过它。


当然你可以有一个setof tuples,因为它们是可散列的。所以,也许你想要这个:

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

这也很容易。假设您的 inner lists 保证只包含字符串(或其他可散列值),就像在您的示例中一样,它只是:

new_set = set(map(tuple, new_list))

或者,如果您使用基于排序的集合类,则不需要可散列值,只需要完全排序的值。例如:

new_set = sortedset(new_list)

Python 的标准库中没有这样的东西,但是你可以安装一些很棒的第三方实现,比如blist.sortedsetbintrees.FastRBTree.

当然,排序集操作通常不如散列操作快,但通常它们已经足够好了。(举个具体的例子,如果列表中有 100 万个项目,散列将使每次查找快 100 万倍;排序只会使其快 50,000 倍。)


基本上,您可以描述或给出示例的任何输出,我们都可以告诉您如何获得它,或者它不是您可以获得的有效对象……但首先您必须告诉我们您真正想要什么。


顺便说一句,如果你想知道为什么lists 不可散列,那只是因为它们是可变的。如果您想知道为什么大多数可变类型不可散列,FAQ对此进行了解释。

于 2013-04-26T18:28:27.457 回答
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')])

集合元素必须是可散列的。

  • 将列表添加到集合中,而不是使用元组
  • 将集合添加到集合中,而不是使用 freezeset
于 2013-04-26T18:31:36.397 回答