9

This is a slight update to my previous question

I have a Python list called results. Most result objects in the results list have a person object, and most person objects have a birthdate property (result.person.birthdate). The birthdate is a datetime object.

I would like to order the list of results by birthdate with the oldest first. However, if there isn't a person object or the person object doesn't have a birthdate I would still like the result included in the list of results. At the end of the list would be ideal.

What is the most Pythonic way to do this?

Community
  • 1
  • 1
shane
  • 1,025
  • 2
  • 11
  • 9

5 Answers5

11
import datetime
results.sort(key=lambda r: r.person.birthdate
    if (r and r.person and r.person.birthdate)
    else datetime.datetime.now())

(P.S. You could have just edited your previous question.)

Amber
  • 507,862
  • 82
  • 626
  • 550
  • 9
    Thank you.I didn't update the original because I thought it may be confusing to start adding new requirements after I had a correct answer. – shane Feb 20 '11 at 09:02
  • 1
    Consider using ``datetime.datetime.max``instead of ``datetime.datetime.now()`` It reads more clean. – bmihelac Apr 17 '15 at 09:06
4
def birthdate_key(x):
  missing = (x.person is None or x.person.birthdate is None)
  return (missing, x.person.birthdate if not missing else None)

results.sort(key=birthdate_key)
Thomas Edleson
  • 2,175
  • 1
  • 16
  • 19
  • I've interpreted "there isn't an attribute of that name" to actually mean there is an attribute, but it is None. If the attribute actually doesn't exist, change both "XXX.name is None" to "not hasattr(XXX, "name")". – Thomas Edleson Feb 20 '11 at 08:50
  • What are you quoting? Where do you see the word "attribute" mentioned in the OP's question? – John Machin Feb 20 '11 at 08:55
  • @John Machin: I've paraphrased. Was it not understandable? – Thomas Edleson Feb 20 '11 at 08:58
0

Maybe monad in Python could be useful here:

from datetime import datetime

def key(result, default=datetime.max):
    try:
         return result.person.birthday or default
    except AttributeError:
         return default

results.sort(key=key)
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

Extract list in which items have None keys and add them to the sorted list.

haystack = [x for x in haystack if x[date_key] is None] + sorted([x for x in haystack if x[date_key] is None], key=lambda x: x[date_key])
Sandeep
  • 28,307
  • 3
  • 32
  • 24
0

I'm interpreting "if there isn't a person object or the person object doesn't have a birthdate" to mean if the result object doesn't have a 'person' attribute and likewise result.person object doesn't have a 'birthdate' attribute. However I notice that your previous question uses strange terminology like "person object set to None" (in a comment). How do you set an object to None? Do you mean person attribute set to None? When you ask a question, (1) please make it standalone and (2) explain fully what your actual data structure.

import datetime
large_date = datetime.datetime(9999, 12, 31)
results.sort(key=lambda result:
    result.person.birthdate 
    if hasattr(result, 'person') and hasattr(result.person, 'birthdate')
    else large_date
    )
John Machin
  • 81,303
  • 11
  • 141
  • 189