2

I am using lambda function to make my code optimize and faster. Below I have written some function.

a = [{"objId":"5c077187fe506f8dd3589ce6","userid":"absurana","firstName":"Null","usrRole":"Software Quality User","lastName":"Null","tiles":"Potential CFD","userType":"User"},
 {"objId":"5d9d7ce6fe506f11b275d01b","userid":"accheung","firstName":"Null","usrRole":"Software Quality User","lastName":"Null","tiles":"Potential CFD",,"userType":"User"},
 {"objId":"5d9d7ce6fe506f11b275d01b","userid":"accheung","firstName":"Null","usrRole":"Software Quality User","lastName":"Null","tiles":"Potential CFD","userType":"User"}]

def function_apply(a):
    for d in a:
        if 'userid' in d:
            d['UserId'] = d.pop('userid')
        if 'userType' in d:
            d['User Type'] = d.pop('userType')
        if 'usrRole' in d:
            d['Role'] = d.pop('usrRole')
        if 'tiles' in d:
            d['Tiles'] = d.pop('tiles')
    return a

Now I want to convert same above function in lambda using map, but getting error. How could I achieve this?

5
  • 2
    Please add you attempt script of your lambda function. Thanks Commented Apr 6, 2020 at 15:12
  • 4
    Why do you assume a lambda function will be faster than a named function? Commented Apr 6, 2020 at 15:13
  • 2
    Lambda expressions produce exactly the same type (function) of values as def statements. Commented Apr 6, 2020 at 15:13
  • 1
    Also, you should not use comprehensions or map for mutational side effects. Commented Apr 6, 2020 at 15:15
  • 3
    In any case, you are iterating over the dicts in a list and modifying them in-place. A for loop is exactly the right construct to be using here, not map. Commented Apr 6, 2020 at 15:15

3 Answers 3

4

A one-liner, concise, pythonic way:

mapping = {"userid": "UserId", "userType": "User Type", "usrRole": "Role", "tiles": "Tiles"}  
def rename(x): return [{mapping.get(k, k):v for (k,v) in d.items()} for d in x]

Please note that the usage of lambda is not providing any computation time gain. Regarding readability, a standard def is the most expected call for a function definition.

>>> rename(a)

[{'objId': '5c077187fe506f8dd3589ce6',
  'UserId': 'absurana',
  'firstName': 'Null',
  'Role': 'Software Quality User',
  'lastName': 'Null',
  'Tiles': 'Potential CFD',
  'User Type': 'User'},
 {'objId': '5d9d7ce6fe506f11b275d01b',
  'UserId': 'accheung',
  'firstName': 'Null',
  'Role': 'Software Quality User',
  'lastName': 'Null',
  'Tiles': 'Potential CFD',
  'User Type': 'User'},
 {'objId': '5d9d7ce6fe506f11b275d01b',
  'UserId': 'accheung',
  'firstName': 'Null',
  'Role': 'Software Quality User',
  'lastName': 'Null',
  'Tiles': 'Potential CFD',
  'User Type': 'User'}]
Sign up to request clarification or add additional context in comments.

3 Comments

There is absolutely no reason to use a lambda expression here. They are intended for anonymous functions, not a way to make your code less readable.
That's a very fair point, I actually (wrongly) use lambdas for one-liner short function definitions. But def also works, and would be more readable. Changing that.
Also, this creates a new dict in each case instead of modifying the original dict in-place. That may or may not be desirable.
2

What you have now is about as efficient as you can get. If you want to make the code less repetitive, you can do something like

key_map = {
    'userid': 'UserId',
    'userType': 'User Type',
    'usrRole': 'Role',
    'tiles': 'Tiles',
}

def function_apply(a):
    for old, new in key_map.items():
        for d in a:
            if old in d:
                d[new] = d.pop(old)

2 Comments

Minor quibble: move the key_map outside of the function so that it is created only once.
Good point; I was thinking CPython, at least, would create the dict when the function was defined, but it does not appear to do so. (Not that such a small dict takes much time to build, but still.)
0

You need a function that can be applied to the individual dicts, e.g:

keys = [
    ('userid', 'UserId'), ('userType', 'User Type'),
    ('usrRole', 'Role'), ('tiles', 'Tiles'),
]

def rename_keys(dct):
    for old, new in keys:
        if old in dct:
            dct[new] = dct.pop(old)

This function can now be applied to the list elements in a loop:

for d in a:
    rename_keys(d)

Using map to do this, is rather pointless:

map(rename_keys, a)

itself does nothing, as the changes will only become effective once the iterator is consumed. So you would have to do something like:

list(map(rename_keys, a))
# or
for _ in map(rename_keys, a): pass

Which illustrates why you shouldn't do it: one creates a spurious in-memory list, the other ends up with a loop anyway. If you don't use the return values of the function, don't use it in map or a comprehension.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.