0

I have the following code:

from datetime import datetime 

ds = "2020.10.10.12.30.59"

y, M, d, h, m, s = [int(x) for x in ds.split('.')]
dt = datetime(y, M, d, h, m, s)

print(dt)

I would like to make it to one-liner something like this:

dt = datetime([int(x) for x in ds.split('.')])

of course this is not working. But can it be done somehow?

pvoj
  • 339
  • 3
  • 14
  • Thank you all for the comments and answers. They are great! 2 important things about the problem: 1. how to unpack the list to parameters. 2. using strptime is the better solution in this application. Thanks again! – pvoj Oct 08 '20 at 15:00

2 Answers2

3

From that point, you just need to spread using unpacking:

dt = datetime(*[int(x) for x in ds.split('.')])

Note the *. This "spreads" the data into each argument.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • 1
    @solid.py I'd wager that a generator would be slower. I've found their overhead is not worth it in cases where you need all the elements immediately, and the iterable is as small as it is here. Also, I try to keep the code as close to the original as I can unless there's a major improvement that's possible. – Carcigenicate Oct 08 '20 at 14:32
  • no need to wager :). For a small scale example you are right https://stackoverflow.com/questions/16307326/why-this-list-comprehension-is-faster-than-equivalent-generator-expression – solid.py Oct 08 '20 at 14:34
  • @Carcigenicate, I'm almost sure that generator will be "faster" and more effective, because additional list won't be created. But I have no idea how to measure such a tiny difference. – Olvin Roght Oct 08 '20 at 14:35
  • 1
    @OlvinRoght My many tests on the difference indicate otherwise; although you'd need to check a particular case to be sure. Consistently, I've seen that unless you actually need the laziness (due to dealing with large data, or conditional processing), it is faster to construct an entire list than it is to lazily produce a generator which you immediately force by doing something like unpacking. – Carcigenicate Oct 08 '20 at 14:38
  • 1
    I've even seen cases where a "pipe" of generators expressions perform worse than a "pipe" of list comprehensions, where it's actually faster to construct several intermediate lists than it is to chain generators. Generators just don't seem to be fast except for in the cases where list comprehensions are unrealistic. – Carcigenicate Oct 08 '20 at 14:45
3

You are really using the wrong tool here; use datetime.strptime() instead:

dt = datetime.strptime(ds, "%Y.%m.%d.%H.%M.%S")

and avoid all that splitting and converting-to-integers work. Moreover, this handles incorrect input better, the %Y pattern to strptime() will not accept a 2-digit year, but the split-and-convert method would accept it, but give you incorrect dates (e.g. 20.10.10.12.30.59 would give you datetime.datetime(20, 10, 10, 12, 30, 59) instead of raising an exception).

If you must use splitting and conversion, then you could use map() to apply int to each split result, then use * to apply the resulting integers as separate arguments:

dt = datetime(*map(int, ds.split(".")))

and this also works with a generator expression:

dt = datetime(*(int(s) for s in ds.split(".")))

Demo:

>>> from datetime import datetime
>>> ds = "2020.10.10.12.30.59"
>>> datetime.strptime(ds, "%Y.%m.%d.%H.%M.%S")
datetime.datetime(2020, 10, 10, 12, 30, 59)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343