объединить элементы словаря в итоговые результаты - PullRequest
0 голосов
/ 15 декабря 2010

У меня есть словарь, как

    mydict={
        (a,1):0,
        (a,2):0,
        (a,3):0,
        (a,4):1,
        (a,5):2,
        (a,6):2,
        (a,7)=0,
        (a,8)=0,           
}

Я хочу обобщить это до

mysummarydict={
    (a,1,3):0,
    (a,4,4):1,
    (a,5,6):2,
    (a,7,8):0
    }

Эти значения взяты из набора данных о интервалах, которые не перекрываются, но могут иметь пропуски. Первый словарь теперь имеет одну запись для каждой отдельной точки, и я хотел бы получить второй словарь, в котором есть сводка тех соседних точек, которые имеют общее значение. Можете ли вы подсказать мне лучшее решение для этого в Python 2.6? Спасибо

Ответы [ 3 ]

2 голосов
/ 15 декабря 2010
from itertools import groupby
from operator import itemgetter

mydict={
        ('a', 1): 0,
        ('a', 2): 0,
        ('a', 3): 0,
        ('a', 4): 1,
        ('a', 5): 2,
        ('a', 6): 2,
        ('a', 7): 0,
        ('a', 8): 0,           
}

data = mydict.items()
data.sort()

def groupkey(item):
    return item[0][0], item[1]

result = {}
for v, group in groupby(data, key=groupkey):
    char, value = v
    nums = [item[0][1] for item in group]
    result[char, min(nums), max(nums)] = value

print result

Результат:

{
 ('a', 1, 3): 0
 ('a', 4, 4): 1, 
 ('a', 5, 6): 2, 
 ('a', 7, 8): 0, 
}
0 голосов
/ 16 декабря 2010

Я нашел более короткий и быстрый метод:

from itertools import groupby
from operator import itemgetter
from time import clock

mydict={('a', 1): 0,
        ('a', 2): 0,
        ('a', 3): 0,
        ('a', 4): 1,
        ('a', 5): 2,
        ('a', 6): 2,
        ('a', 7): 0,
        ('a', 8): 0,
        }

A,B,C = [],[],[]

for i in xrange(1000):

    t0 = clock()
    data = mydict.items()
    data.sort()
    def groupkey(item):
        return item[0][0], item[1]
    result1 = {}
    for v, group in groupby(data, key=groupkey):
        char, value = v
        nums = [item[0][1] for item in group]
        result1[char, min(nums), max(nums)] = value
    A.append(clock()-t0)

    #----------------------------------------------------------------

    t0 = clock()
    data = [ [a,b,c] for ((a,b),c) in mydict.items()]
    data.sort()
    result2 = {}
    for (char,value),group in groupby(data, key=itemgetter(0,2)):
        nums = [item[1] for item in group]
        result2[char,nums[0],nums[-1]] = value
    B.append(clock()-t0)

    #-----------------------------------------------------------------

    t0 = clock()
    data = [ [a,b,c] for ((a,b),c) in mydict.items()]
    data.sort()
    result3 = {}
    for ((char,value),nums) in [ (cle,[item[1] for item in group]) for cle,group in groupby(data, key=itemgetter(0,2))]:
        result3[char,nums[0],nums[-1]] = value
    C.append(clock()-t0)

print 'result1==',result1
print 'result2==',result2
print 'result3==',result3
print 'result1==result2==result3==',result1==result2==result3
print id(result1)==id(result2),id(result2)==id(result3),id(result3)==id(result1)


print '{:.1%}.'.format(min(B)/min(A))
print '{:.1%}.'.format(min(C)/min(A))

результат:

result1 == {('a', 5, 6): 2, ('a', 4, 4): 1, ('a', 7, 8): 0, ('a', 1, 3): 0}

result2 == {('a', 5, 6): 2, ('a', 4, 4): 1, ('a', 7, 8): 0, ('a', 1, 3): 0}

result3 == {('a', 5, 6): 2, ('a', 4, 4): 1, ('a', 7, 8): 0, ('a', 1, 3): 0}

result1 == result2 == result3 == True

Ложь Ложь Ложь

87,0%.

93,2%.

0 голосов
/ 15 декабря 2010

Если вместо этого вы сохраните эти данные в списке, это станет намного проще:

from itertools import groupby
from operator import itemgetter

mylist = [0, 0, 0, 1, 2, 2, 0, 0]

def interval(v):
    head = tail = next(v)
    for tail in v:
        pass

    return head[0] + 1, tail[0] + 1

print({interval(v): k for k, v in groupby(enumerate(mylist), key=itemgetter(1))})

, что дает

{(5, 6): 2, (1, 3): 0, (7, 8): 0, (4, 4): 1}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...