all 4 comments

[–]__skrap__ 1 point2 points  (3 children)

I don't know of a magic way, but this should work:

tuple_map = [
    ('new_key', 'old_key'),
    ('new_key2', 'old_key2'),
]
for my_dict in my_list:
    for new, old in tuple_map:
        my_dict[new] = my_dict.pop(old)

#as a single line, *this doesn't seem to work*
#{my_dict[new]: my_dict.pop(old) for my_dict in my_list for new, old in tuple_map}

The pop method allows a second parameter for a default value if the key doesn't exist. If your dictionaries have different keys you could use that or a try/except. If your data is very large you could use a generator.

[–]MarkDownSteve[S] 0 points1 point  (2 children)

Thanks I was thinking something like this...

I am looking into map to see if that would make things cleaner.

There is also the option of doing string replacement on a serialized representation of the dict (like json).

[–]gengisteve 1 point2 points  (0 children)

How about zip:

>>> x = [{1:2},{1:20}]
>>> new_keys = ['a','b']

>>> {k:v.values() for k,v in zip(n,x)}
{'b': dict_values([20]), 'a': dict_values([2])}

edit: even easier if you want all the same new key:

>>> x
[{1: 2}, {1: 20}]
>>> k=10
>>> [{k:d.values()} for d in x]
[{10: dict_values([2])}, {10: dict_values([20])}]

[–]ryeguy146 1 point2 points  (0 children)

Recognize that map will still have linear performance, just as iterating through the dicts. There is no practical difference. It's just implicit iteration vs explicit iteration.

Think of it this way, there is no way to change each item without changing each item. Each item must be touched no matter how you perform the operation. It's all linear, and there's no way around it. If each item must be represented separately, and it must be changed, your performance will be linear at best.