在python中创建唯一列表

时间:2012-10-26 08:53:14

标签: python

使用自定义相等运算符使列表唯一的最pythonic方法是什么?

例如,您有一个词条L列表,并且您需要一个新列表M,以便d中的所有词组eM和一个特定的x

d[x] != e[x]

如何做到这一点?

4 个答案:

答案 0 :(得分:3)

在你的情况下(以及等价归结为某种键的等价的所有情况),你可以简单地构造一个字典,其中键是你想要比较的值:

L = [{'key': 'foo', 'v': 42}, {'key': 'bar', 'v': 43}, {'key': 'foo', 'v': 44}]
x = 'key'
M = {d[x]:d for d in L}.values()
# In old Python versions: dict((d[x],d for d in L)).values()

请注意,结果不具有确定性,

[{'key': 'foo', 'v': 44}, {'key': 'bar', 'v': 43}]

[{'key': 'foo', 'v': 42}, {'key': 'bar', 'v': 43}]

是有效的结果。

在一般情况下,只需检查所有接受的值:

def unique(iterable, is_eq):
  tmp = []
  for el in iterable:
    if not any(is_eq(inTmp, el) for inTmp in tmp):
      tmp.append(is_eq)
  return tmp

请注意,这意味着您的比较函数将被调用O(n²)次而不是n次。

答案 1 :(得分:1)

基于FUD对phihag的评论。请注意,key函数必须返回哈希值。

def unique(iterable, key=lambda x : x):
    seen = set()
    res = []
    for item in iterable:
        k = key(item)
        if k not in seen:
            res.append(item)
            seen.add(k)
    return res

from operator import itemgetter
L = [{'key': 'foo', 'v': 42}, {'key': 'bar', 'v': 43}, {'key': 'foo', 'v': 44}]
print unique(L, key=itemgetter('key'))
#[{'key': 'foo', 'v': 42}, {'key': 'bar', 'v': 43}]

答案 2 :(得分:0)

我不确定这种事情是否允许单行,但在我看来,set类是你想要的关键。

M = []
uniques = set(d[x] for d in L)
for d in L:
    if d[x] in uniques:
        uniques.remove(d[x])
        M.append(d)

注意:phihag的答案似乎更像Pythonic,但这可能会更加自我记录

答案 3 :(得分:0)

使用字典理解:

def unique(itrable,key):
    return {key(x):x for x in itrable}.values()

>>> unique('abcdbbcdab', lambda x: x)
['a', 'c', 'b', 'd']

>>> unique([10, -20, 20, 30], lambda x: abs(x))
[10, 20, 30]