Python:如何使用list来获得唯一值

时间:2015-03-11 20:46:43

标签: python

我遇到的问题如下:我从一个过程得到一组值:

t=903
a=432
c=335

这些值在字典中,它将t,a和c的不同序列分配给不同的键

{key1} : (t1 a1 c1, t2 a2 c2, ...tn an cn)
{key2} : (t1 a1 c1, t2 a2 c2, ...tn an cn)

我想要的是,如果第一个值(比如说t)已经存在,则不向键添加三元组值。基本上我会使用“t”变量作为我的三元组的唯一因子。这仅适用于每个键,所以我不介意我在键2上有相同的值...键n;重要的是每个键都有一个唯一的t值,只有当“t”的值是唯一的时,才会在字典中写入3个值。

我试过了:

for triplets in dict[key1]:
    if not t in triplets:
        dict[key1].append(t,a,c)

但这似乎不起作用。我是否通过字典错误地骑车?我应该使用不同的结构吗?

2 个答案:

答案 0 :(得分:2)

你可以创建另一个级别;每个值都是t上键入的词典:

tripplets = dict.setdefault(key1, {})
if t not in triplets:
    triplets[t] = (t, a, c)

这会产生:

{
    'key1': {'t1': (t1, a1, c2),
             't2': (t2, a2, c2)},
    ...
}

所以,如果(t?, a?, c?)不是t?字典中的关键字,则只需添加dict[key1]

您还可以使用实现__eq____hash__的自定义类替换您的三值元组,如果它们的t值相等,则认为它们相等:

class Entry(object):
    __slots__ = ('t', 'a', 'c')  # save some memory
    def __init__(self, t, a, c):
        self.t = t
        self.a = a
        self.c = c
    def __eq__(self, other):
        if not isinstance(other, Entry): return NotImplemented
        return self.t == other.t
    def __hash__(self):
        return id(self.t)
    def __repr__(self):
        return '<{0}({1[0]!r}, {1[1]!r}, {1[2]!r})>'.format(type(self).__name__, self)
    def __getitem__(self, index):
        return getattr(self, 'tac'[index])

然后在词典中使用集合:

dict(key1, set()).add(Entry(t, a, c))

但是,如果您有时希望t保持唯一,而其他时间保持ac,则无需进行实际搜索。如果找到匹配项,请使用any() function提前纾困:

triplets = dict.setdefault(key1, [])
if not any(triplet[0] == t for triplet in triplets):
    # no such t value found
    triplets.append((t, a, c))

答案 1 :(得分:0)

这听起来很像......第二本字典!您可以按如下方式实现数据结构:

from collections import defaultdict

items = defaultdict(dict)

def add_entry(items, key, t, a, c):
    values = items[key]
    if t not in values:
        values[t] = (a,c)

def get_entry(items, key):
    values = items[key]
    entry  = []
    for t, (a,c) in values.iteritems():
        entry.extend((t,a,c))
    return entry

用法:

>>> add_entry(items, "test", 1, 2, 3)
>>> get_entry(items, "test")
[1, 2, 3]
>>> add_entry(items, "test", 2, 2, 3)
>>> get_entry(items, "test")
[1, 2, 3, 2, 2, 3]
>>> add_entry(items, "test", 1, 6, 7)
>>> get_entry(items, "test")
[1, 2, 3, 2, 2, 3]
>>> add_entry(items, "test2", 1, 2, 3)
>>> get_entry(items, "test2")
[1, 2, 3]

如果您想要获取元组列表而不仅仅是值列表,请将entry.extend((t,a,c))替换为entry.append((t,a,c))

当然,如果您愿意,可以将此数据结构及其操作方法封装到一个类中,以获得更好的可用性,如下所示:

class EntryManager(object):

    def __init__(self):
        self._items = defaultdict(dict)

    def add_entry(self, key, t, a, c):
        values = self._items[key]
        if t not in values:
            values[t] = (a,c)

    def get_entry(self, key):
        values = self._items[key]
        entry  = []
        for t, (a,c) in values.iteritems():
            entry.extend((t,a,c))
        return entry