2012-01-13 9 views
0
t = ({'x':1}, {'x':1}, {'y':2}) 

Я унифицировать его с помощью:Как объединить избыточные кортежи словаря?

l = [] 
for i in t: 
    if i not in l: 
     l.append(i) 

tuple(l) 

дает результат ({'x': 1}, {'y': 2})

Есть ли лучший способ для этого?

Другой образец входного = ({'x':1, 'y':1}, {'x':3}, {'x':1, 'y':2}, {'x':1, 'y':2}) Пример вывода: ({'x':1, 'y':1}, {'x':3}, {'x':1, 'y':2})

+0

насчет '({' х ': 1}, {' х ': 2})' – Dave

+0

, что ваш ожидаемый результат? – juliomalegria

+0

Я обновил свой вопрос с помощью примера ввода/вывода – discky

ответ

4

EDIT: совершенно другой ответ на вопрос, как он был обновлен:

dict([(x.items()[0], x) for x in t]).values() 

Это происходит каждый Dict и преобразует его в кортеж. Кортеж hashable, поэтому он может использоваться как ключ в словаре. Затем он создает dict с хешированным кортежем как ключ и оригинал dict в качестве значения. Это означает, что один и тот же dict хранится только один раз. Затем мы берем значения из dict как list. А затем постройте tuple.

>>> t = ({'x':1, 'y':1}, {'x':3}, {'x':1, 'y':2}, {'x':1, 'y':2}) 
>>> tuple(dict([(x.items()[0], x) for x in t]).values()) 
({'y': 1, 'x': 1}, {'x': 3}, {'y': 2, 'x': 1}) 
+0

Эта последовательность должна указывать: ({'x': 1}, {'y': 2}, {'y': 3}, {'x': 4, 'p': 9 }) – discky

+0

результат должен быть кортежем dict. Не указывать разные ключи. – discky

+0

все еще не заполняет все case.t = ({'x': 1, 'y': 1}, {'x': 3}, {'x': 2, 'y': 2}, {'x' : 1, 'y': 2}) должно возвращать то же значение. Потому что ни один из двух словарей не является одинаковым. Решение выдает [{'x': 1, 'y': 1}, {'x': 3}, {'x': 1, 'y': 2}]. – discky

1

Следующая один лайнер работает:

dict([i.items()[0] for i in t]) 
+0

Не обрабатывает второй пример OP, где большинство словарей имеют более одного элемента. Независимо от того, в вашем ответе '[]' для создания промежуточного «списка» не нужны, поскольку это выражение генератора. – martineau

0

Это может потребовать переосмысления того, что вам нужно, но наборы сделаны для этого.

>>> t = (("x",1), ("x",1), ("y", 2)) 
>>> set(t) 
set([('x', 1), ('y', 2)]) 
1

Я думаю, что комплект может удовлетворить все потребности. Но dict не удовлетворяет требованию члена set-hashability, поэтому нам нужна обертка.

class HashableDictWrapper(object): 
     def __init__(self, di): 
      self.di = di 
      self._hash_key = id("".join(["%s=%s" % (k, di[k]) for k in sorted(di.iterkeys())])) 

     def __hash__(self): 
      return self._hash_key 

     def __eq__(self, other): 
      return self.__hash__()==other.__hash__() 

if __name__=="__main__": 
     t = ({'x':1}, {'x':1}, {'y':2}) 
     s = set(map(HashableDictWrapper, t)) 
     tuple(map(lambda a:a.di, s)) 

ОБНОВЛЕНО: я внести некоторые изменения в @monkut 'ы ответ:

t = ({'x':1}, {'x':1}, {'y':2}) 
p = map(lambda di:tuple((k,di[k]) for k in sorted(di.iterkeys())), t) 
result = tuple(map(lambda x:dict(x), set(p))) 
Смежные вопросы