RonnyKnoxville
RonnyKnoxville

Reputation: 6394

Get first element of list if list is not None: Python

Here is my issue:

I am doing an LDAP search in Python. The search will return a dictionary object:

{'mail':['[email protected]'],'mobile':['07852242242'], 'telephoneNumber':['01112512152']}

As you can see, the returned dictionary contains list values.

Sometimes, no result will be found:

{'mail':None, 'mobile':None, 'telephoneNumber':['01112512152']}

To extract the required values, I am using get() as to avoid exceptions if the dictionary item does not exist.

return {"uname":x.get('mail')[0], "telephone":x.get('telephoneNumber')[0], "mobile":x.get('mobile')[0]}

I want to return my own dictionary as above, with just the string values, but Im struggling to find an efficient way to check that the lists are not None and keep running into index errors or type errors:

(<type 'exceptions.TypeError'>, TypeError("'NoneType' object is unsubscriptable",)

Is there a way to use a get() method on a list, so that if the list is None it wont throw an exception???

{"uname":x.get('mail').get(0)}

What is the most efficient way of getting the first value of a list or returning None without using:

if isinstance(x.get('mail'),list):

or

if x.get('mail') is not None:

Upvotes: 2

Views: 6242

Answers (4)

soulcheck
soulcheck

Reputation: 36767

I'm not sure if there's a straightforward way to do this, but you can try:

 default_value = [None]
 new_x = dict((k, default_value if not v  else v) for k, v in x.iteritems())

And use new_x instead of x.

Upvotes: 0

Rik Poggi
Rik Poggi

Reputation: 29302

If you want to flatten your dictionary, you can just do:

>>> d = {'mail':None, 'mobile':None, 'telephoneNumber':['01112512152']}
>>> 
>>> dict((k,v and v[0] or v) for k,v in d.items())
{'mail': None, 'mobile': None, 'telephoneNumber': '01112512152'}

If you'd also like to filter, cutting off the None values, then you could do:

>>> dict((k,v[0]) for k,v in d.items() if v)
{'telephoneNumber': '01112512152'}

Upvotes: 3

Sam Dolan
Sam Dolan

Reputation: 32532

You could do something like this:

input_dict = {'mail':None, 'mobile':None, 'telephoneNumber':['01112512152']}

input_key_map = {
    'mail': 'uname',
    'telephoneNumber': 'telephone',
    'mobile': 'mobile',
}

dict((new_name, input_dict[old_name][0]) 
      for old_name, new_name in input_key_map.items() if input_dict.get(old_name))

# would print:
{'telephone': '01112512152'}

Upvotes: 0

Roman Bodnarchuk
Roman Bodnarchuk

Reputation: 29727

Try the next:

return {"uname":(x.get('mail') or [None])[0], ...

It is a bit unreadable, so you probably want to wrap it into some helper function.

Upvotes: 2

Related Questions