列表列表的唯一性

问题描述 投票:0回答:8

我很好奇什么是唯一化此类数据对象的有效方法:

testdata =[ ['9034968', 'ETH'], ['14160113', 'ETH'], ['9034968', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15724032', 'ETH'], ['15481740', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['10307528', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['15481740', 'ETH'], ['15379365', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15379365', 'ETH']
]

对于每个数据对,左侧的数字字符串加上右侧的类型表明数据元素的唯一性。返回值应该是与测试数据相同的列表列表,但仅保留唯一值。

python unique
8个回答
169
投票

您可以使用一套:

unique_data = [list(x) for x in set(tuple(x) for x in testdata)]

您还可以看到此页面,它对保留或不保留顺序的各种方法进行了基准测试。


11
投票

我尝试了@Mark的答案并收到错误。将列表和每个元素转换为元组使其工作。不确定这是否是最好的方法。

list(map(list, set(map(lambda i: tuple(i), testdata))))

当然可以使用列表理解来表达同样的事情。

[list(i) for i in set(tuple(i) for i in testdata)]

我正在使用Python 2.6.2。

更新

@Mark 此后改变了他的答案。他当前的答案使用元组并且会起作用。我的也一样:)

更新2

感谢@Mark。我更改了答案以返回列表列表而不是元组列表。


6
投票

使用unique

中的
numpy
来解决这个问题:

import numpy as np

np.unique(np.array(testdata), axis=0)

请注意,需要指定

axis
关键字,否则列表将首先被展平。

或者,使用

vstack
:

np.vstack({tuple(row) for row in testdata})

3
投票

稍微扩展一下 @Mark Byers 解决方案,您也可以只进行一个列表理解和类型转换来获得您需要的内容:

testdata = list(set(tuple(x) for x in testdata))

此外,如果您不喜欢列表推导式,因为许多人觉得它们令人困惑,您可以在 for 循环中执行相同的操作:

for i, e in enumerate(testdata):
    testdata[i] = tuple(e)
testdata = list(set(testdata))

2
投票
import sets
testdata =[ ['9034968', 'ETH'], ['14160113', 'ETH'], ['9034968', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15724032', 'ETH'], ['15481740', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['10307528', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['15481740', 'ETH'], ['15379365', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15379365', 'ETH']]
conacatData = [x[0] + x[1] for x in testdata]
print conacatData
uniqueSet = sets.Set(conacatData)
uniqueList = [ [t[0:-3], t[-3:]] for t in uniqueSet]
print uniqueList

1
投票

如果您有一个对象列表,则可以修改@Mark Byers的答案:

unique_data = [list(x) for x in set(tuple(x.testList) for x in testdata)]

其中 testdata 是具有列表 testList 作为属性的对象列表。


1
投票

我正要发表我自己的看法,直到我注意到 @pyfunc 已经提出了类似的东西。无论如何,我都会发布我对这个问题的看法,以防有帮助。

testdata =[ ['9034968', 'ETH'], ['14160113', 'ETH'], ['9034968', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15724032', 'ETH'], ['15481740', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['10307528', 'ETH'], ['15481757', 'ETH'], ['15481724', 'ETH'], ['15481740', 'ETH'], ['15379365', 'ETH'], ['11111', 'NOT'], ['9555269', 'NOT'], ['15379365', 'ETH']
]
flatdata = [p[0] + "%" + p[1] for p in testdata]
flatdata = list(set(flatdata))
testdata = [p.split("%") for p in flatdata]
print(testdata)

基本上,您使用列表理解将列表中的每个元素连接成单个字符串,这样您就拥有了单个字符串的列表。这样就更容易变成一套,这使得它独一无二。然后您只需将其拆分到另一端并将其转换回原始列表即可。

我不知道这在性能方面如何比较,但我认为这是一个简单且易于理解的解决方案。


0
投票

保留顺序(Python 3.7+)

  • 内部列表变成元组:

    list({tuple(x): 1 for x in testdata})
    
  • 内部列表保留为列表:

    list(map(list, {tuple(x): 1 for x in testdata}))
    
© www.soinside.com 2019 - 2024. All rights reserved.