Найти - Пользователи
Полная версия: Замена значений в последовательности пар
Начало » Python для новичков » Замена значений в последовательности пар
1 2
Yettee
Доброго времени суток!

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

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

Прошу прощения, я не шибко опытен, но разве OrderedDict - стандартная библиотека?
pyuser
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
FishHook
А если еще проще сделать?
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
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'))
FishHook
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
Yettee
Большое спасибо!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB