Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 10, 2012 00:21:53

Yettee
Зарегистрирован: 2012-04-10
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

Доброго времени суток!

Есть кортеж из парных элементов, в котором содержатся атрибуты HTML тега и их значения.
Необходимо найти атрибут и изменить его значение. Как это аккуратно сделать?
Я попытался преобразовать кортеж в словарь, по ключу-атрибуту заменить значение и преобразовать словарь обратно в последовательность парных элементов. НО! При преобразовании в словарь порядок следования элементов кортежа меняется. Мне же необходимо сохранить порядок элементов.
Заранее спасибо за помощь.

Офлайн

#2 Апрель 10, 2012 01:02:45

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

collections.OrderedDict ?

Офлайн

#3 Апрель 10, 2012 01:11:30

Yettee
Зарегистрирован: 2012-04-10
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

s0rg
collections.OrderedDict ?

Вариант интересный, но хотелось бы максимально просто и с минимумом дополнительного стороннего кода

Офлайн

#4 Апрель 10, 2012 01:25:00

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

Проще и минимальней, чем стандартная библиотека?
Увы, не выйдет.

Офлайн

#5 Апрель 10, 2012 01:30:05

Yettee
Зарегистрирован: 2012-04-10
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

s0rg
Проще и минимальней, чем стандартная библиотека?
Увы, не выйдет.

Прошу прощения, я не шибко опытен, но разве OrderedDict - стандартная библиотека?

Офлайн

#6 Апрель 10, 2012 03:02:34

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

OrderedDict, в данном случае, накладное решение

from collections import OrderedDict
from timeit import Timer
def with_dict(src, key, value):
    tmp = OrderedDict(src)
    tmp[key] = value
    return tmp.items()
def forehead(src, key, value):
    for k, v in src:
        yield (k, value) if k == key else (k, v)
if "__main__" == __name__:
    tag = (("key1", "value1"), ("key2", "value2"), ("key3", "value3"),
           ("key4", "value4"), ("key5", "value5"), ("key6", "value6"))
    print(list(with_dict(tag, 'key2', 'new_key2_value')))
    print(list(forehead(tag, 'key2', 'new_key2_value')))
    t1 = Timer("list(with_dict(tag, 'key2', 'new_key2_value'))",
            "from __main__ import with_dict, tag")
    t2 = Timer("list(forehead(tag, 'key2', 'new_key2_value'))",
            "from __main__ import forehead, tag")
    print(t1.timeit())
    print(t2.timeit())
результат:
[('key1', 'value1'), ('key2', 'new_key2_value'), ('key3', 'value3'), ('key4', 'value4'), ('key5', 'value5'), ('key6', 'value6')]
[('key1', 'value1'), ('key2', 'new_key2_value'), ('key3', 'value3'), ('key4', 'value4'), ('key5', 'value5'), ('key6', 'value6')]
28.236345401440683
2.163669614434234



Офлайн

#7 Апрель 10, 2012 06:22:11

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

А если еще проще сделать?

def change_tag(tag, key,value):
	return [(k,value) if k==key else (k,v) for k,v in tag]
from collections import OrderedDict
from timeit import Timer
def with_dict(src, key, value):
    tmp = OrderedDict(src)
    tmp[key] = value
    return tmp.items()
def forehead(src, key, value):
    for k, v in src:
        yield (k, value) if k == key else (k, v)
def change_tag(tag, key,value):
	
	return [(k,value) if k==key else (k,v) for k,v in tag]
if "__main__" == __name__:
    tag = (("key1", "value1"), ("key2", "value2"), ("key3", "value3"),
           ("key4", "value4"), ("key5", "value5"), ("key6", "value6"))
    print list(with_dict(tag, 'key2', 'new_key2_value'))
    print list(forehead(tag, 'key2', 'new_key2_value'))
    print change_tag(tag, 'key2', 'new_key2_value')
    t1 = Timer("list(with_dict(tag, 'key2', 'new_key2_value'))",
            "from __main__ import with_dict, tag")
    t2 = Timer("list(forehead(tag, 'key2', 'new_key2_value'))",
            "from __main__ import forehead, tag")
    t3 = Timer("change_tag(tag, 'key2', 'new_key2_value')",
            "from __main__ import change_tag, tag")
    
    print t1.timeit()
    print t2.timeit()
    print t3.timeit()

[('key1', 'value1'), ('key2', 'new_key2_value'), ('key3', 'value3'), ('key4', 'value4'), ('key5', 'value5'), ('key6', 'value6')]
[('key1', 'value1'), ('key2', 'new_key2_value'), ('key3', 'value3'), ('key4', 'value4'), ('key5', 'value5'), ('key6', 'value6')]
[('key1', 'value1'), ('key2', 'new_key2_value'), ('key3', 'value3'), ('key4', 'value4'), ('key5', 'value5'), ('key6', 'value6')]
28.1137778759
1.90166282654
1.11240196228



Офлайн

#8 Апрель 10, 2012 08:04:40

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

FishHook
А если еще проще сделать?
Почему бы и нет? Хотя, генератор, ИМХО, удобнее. Код:
' '.join('{}="{}"'.format(k, v) for k, v in forehead(tag, 'key2', 'new_key2_value'))
# внезапно :)
from itertools import starmap
" ".join(starmap('{}="{}"'.format,  forehead(tag, 'key2', 'new_key2_value')))
будет выполняться быстрее и с меньшей загрузкой памяти чем:
' '.join('{}="{}"'.format(k, v) for k, v in change_tag(tag, 'key2', 'new_key2_value'))



Отредактировано pyuser (Апрель 10, 2012 08:29:34)

Офлайн

#9 Апрель 10, 2012 08:47:22

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

pyuser
FishHook
А если еще проще сделать?
Почему бы и нет? Хотя, генератор, ИМХО, удобнее. Код:
' '.join('{}="{}"'.format(k, v) for k, v in forehead(tag, 'key2', 'new_key2_value'))
# внезапно :)
from itertools import starmap
" ".join(starmap('{}="{}"'.format,  forehead(tag, 'key2', 'new_key2_value')))
будет выполняться быстрее и с меньшей загрузкой памяти чем:
' '.join('{}="{}"'.format(k, v) for k, v in change_tag(tag, 'key2', 'new_key2_value'))
Про оперативу спорить не буду, но тест показывает, что в скорости генератор проигрывает
from timeit import Timer
def forehead(src, key, value):
    for k, v in src:
        yield (k, value) if k == key else (k, v)
def change_tag(tag, key,value):
	return [(k,value) if k==key else (k,v) for k,v in tag]
def a(tag):
    return ' '.join('{}="{}"'.format(k, v) for k, v in forehead(tag, 'key2', 'new_key2_value'))
def b(tag):
    return ' '.join('{}="{}"'.format(k, v) for k, v in change_tag(tag, 'key2', 'new_key2_value'))
if "__main__" == __name__:
    tag = [("key%s" % i, "value%s" %i) for i in xrange(100)]
    
        
    t2 = Timer("a(tag)",
            "from __main__ import tag, a")
    t3 = Timer("b(tag)",
            "from __main__ import  tag, b")
    
    
    print t2.timeit()
    print t3.timeit()
56.172315836
52.7263169289



Офлайн

#10 Апрель 10, 2012 22:12:59

Yettee
Зарегистрирован: 2012-04-10
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Замена значений в последовательности пар

Большое спасибо!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version