2013-04-15 23 views
3

所以在Python 2,你可以使用类似什么是找到独特的unhashable unorderable类型在Python 3

>>> items = [[1, 2], [3], [3], 4, 'a', 'b', 'a'] 
>>> from itertools import groupby 
>>> [k for k, g in groupby(sorted(items))] 
[4, [1, 2], [3], 'a', 'b'] 

效果很好,在O(N log N)时间的最佳方式。然而Python 3感叹TypeError: unorderable types: int() < list()。那么在Python 3中完成它的最好方法是什么? (我知道最好的是一个主观的术语,但真的应该有一种方法,根据Python做到这一点)

编辑:它不必使用排序,但我猜这将是最好的方式

+0

那些列表可以不是元组吗? –

+0

@JakobBowyer原谅我没有想到一个更好的例子,为了这个问题,它的标题,让我们说他们不能 – user2282357

+1

@JakobBowyer:这不会有什么帮助;那么他只会得到一个关于'int'和'tuple'不可订购的错误。 – abarnert

回答

5

在2.x中,两个不可分的内置类型的值按类型排序。没有定义类型的顺序,除了在解释器的一次运行期间它将保持一致。所以,2 < [2]可能是真或假,但它会是一致是真是假。

在3.x中,无比内置类型的值是无法比拟的,这意味着它们养TypeError如果您尝试对它们进行比较。所以,2 < [2]是一个错误。而且,至少从3.3开始,类型本身甚至没有可比性。但是如果你想重现的只是2.x行为,那么它们在解释器运行期间是绝对可比的并且是一致的。所以:

sorted(items, key=lambda x: (id(type(x)), x)) 

对于您的用例,这就是您所需要的。


然而,这将不会是准确的是2.x的做同样的事情,因为这意味着,例如,1.5 < 2可以是False(因为float>int)。如果您想要复制确切的行为,则需要编写一个首先尝试比较值的关键函数,然后在TypeError上返回比较类型。

这是极少数情况下旧式cmp功能是一个容易得多比一个新型key函数读取一个,所以让我们写这些的一个,然后在其上使用cmp_to_key

def cmp2x(a, b): 
    try: 
     if a==b: return 0 
     elif a<b: return -1 
     elif b<a: return 1 
    except TypeError: 
     pass 
    return cmp2x(id(type(a)), id(type(b))) 
sorted(items, key=functools.cmp_to_key(cmp2x)) 

这仍然不能保证相同的顺序不同类型的2.X将给出两个值之间,但由于2.x中没有定义任何命令(只是它一个运行中的一致),有没有办法它可以。但是,如果你定义一个类的对象不是完全有序的,它们将最终按照相等的顺序进行排序,而我不确定这是2.x会做的同样的事情在这种情况下。

+0

我不是Python专家,但是,是不是应该解决这类问题的字典? '{“key”:value,...}' – user2244984

+1

@ user2244984:我不确定字典如何解决与原始问题相关的任何问题。集合会......但整个问题是值不可散列,这意味着它们不能用于集合或字典。 – abarnert

+0

好的,我需要一个**不可取的定义**,因为这是我第一次读这个术语的时间:什么是不可哈呢? – user2244984

1

让我们退后一步。

你想uniquify集合。

如果值是哈希的,你应该使用O(N)set解决方案。但他们不是。如果你能想出某种散列函数,你可以等效地使用的myhash(value): value。如果你的使用情况真的是“没有什么,但可哈希值和平板list小号可哈希值”,你可以做到这一点try荷兰国际集团以hash,然后回落到hash(tuple())。但总的来说,这是行不通的。

如果它们是完全有序的,那么您可以使用O(N log N)sorted解决方案(或等价的基于树的解决方案或类似方法)。如果您可以想出某种完整的订购功能,您只需将key传递给sorted函数即可。我认为这将在你的用例中起作用(因此我的其他答案)。但是,如果不是的话,没有O(N日志N)解决方案将工作。

如果他们没有,你可以回落到O(N ** 2)线性搜索解决方案:

unique = [] 
for value in items: 
    if value not in unique: 
     unique.append(value) 

如果你不能找到一些方式来定义一个完整的排序或哈希函数对你的值,这是你能做的最好的。

相关问题