Форум сайта python.su
0
Доброго времени суток!
Есть кортеж из парных элементов, в котором содержатся атрибуты HTML тега и их значения.
Необходимо найти атрибут и изменить его значение. Как это аккуратно сделать?
Я попытался преобразовать кортеж в словарь, по ключу-атрибуту заменить значение и преобразовать словарь обратно в последовательность парных элементов. НО! При преобразовании в словарь порядок следования элементов кортежа меняется. Мне же необходимо сохранить порядок элементов.
Заранее спасибо за помощь.
Офлайн
25
collections.OrderedDict ?
Офлайн
0
s0rg
collections.OrderedDict ?
Офлайн
25
Проще и минимальней, чем стандартная библиотека?
Увы, не выйдет.
Офлайн
0
s0rg
Проще и минимальней, чем стандартная библиотека?
Увы, не выйдет.
Офлайн
36
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
Офлайн
568
А если еще проще сделать?
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
Офлайн
36
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)
Офлайн
568
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
Офлайн
0
Большое спасибо!
Офлайн