0

I just started programming with Python, and have some simple questions (probably). What I would like to do is compare some timestamps to find the closest that isn't later then now.

Basically what Iam trying to do is getting the current track played on the radio, and they have a feed that show the next 20 or so with time for when the track starts. I want to get whats playing right now!

Here is an example array of strings:

examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']

Now what I would like to do is compare the time closest to now (but not later) to see whats currently playing.

This is my script so far:

import datetime, itertools, time
currentTimeMachine = datetime.datetime.now()
now = currentTimeMachine.strftime("%Y-%m-%d %H:%M:%S")

examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
tmsg = examples.strftime('%d%b%Y')


 print [x for x in itertools.takewhile( lambda t: now > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), examples )][-1]

The last bit there I picked up somwhere else, but I cant seem to get it to work.

Any help would be greatly appreciated!

4

3 に答える 3

1

datetime.datetime.strptime()文字列を日時オブジェクトに変換するために使用します。

>>> import datetime
>>> examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
>>> parsed_datetimes = [datetime.datetime.strptime(e, "%Y-%m-%d %H:%M:%S") for e in examples]
>>> parsed_datetimes
[datetime.datetime(2012, 12, 10, 2, 6, 45), datetime.datetime(2012, 12, 10, 2, 2, 43), datetime.datetime(2012, 12, 10, 1, 58, 53)]

これにより、現在の日時から「現在に最も近い」日時の最小差が取得されnowます。

>>> now = datetime.datetime.now()
>>> min_time_diff, min_datetime = min((now - i, i) for i in parsed_datetimes)
>>> min_time_diff, min_datetime
(datetime.timedelta(0, 36265, 626000), datetime.datetime(2012, 12, 10, 2, 6, 45))
于 2012-12-10T01:56:57.873 に答える
1

エラーメッセージを投稿しなかったため、投稿したコードに基づいて、いくつかの問題があります

1)tmsg = examples.strftime('%d%b%Y')リストの strftime に呼び出しを適用するため、機能しません

2) 他の人がすでに指摘しているように、takewhile では string と datetime を比較しています。

これはうまくいきます:

>>> import datetime, itertools, time
>>> currentTimeMachine = datetime.datetime.now()
>>> print [x for x in itertools.takewhile( lambda t: currentTimeMachine  > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), examples )][-1]
2012-12-10 01:58:53
于 2012-12-10T02:00:40.757 に答える
1

他の回答でエラーが修正されたため、アルゴリズムが適切に実行されるようになりました。

しかし、アルゴリズム自体が間違っています。行き過ぎずに今に一番近づきたい。しかし、あなたが書いたものは次のとおりです。

 [x for x in itertools.takewhile(pred, examples)][-1]

これが何を意味するか考えてみてください。まず、takewhileいずれかが述語に失敗するまで例を返します。次に、成功した最後のものを取得しています。したがって、例が次のようになっているとします。

[now-3, now-10, now-5, now+3, now-9, now-1, now+9]

False を返すため、最初にtakewhile譲歩now-3, now-10, now-5してから停止します。pred(now+3)次に、最後の 1 つを取りますnow-5

例を昇順で並べ替えると、これが機能します。

[now-10, now-9, now-5, now-3, now-1, now+3, now+9]

Nowは までのtakewhileすべてを生成するnow-1ので、最後に生成されるのはあなたが望むものです。

しかし、最初の質問の例は降順であり、Anthony Kong の回答へのコメントでは、まったく順序になっていないものをいくつか追加しました。したがって、明らかにそれらがソートされていることに依存することはできません。したがって、考えられる修正の 1 つは、それらを並べ替えることです。

>>> import datetime, itertools, time
>>> currentTimeMachine = datetime.datetime.now()
>>> print [x for x in itertools.takewhile(lambda t: currentTimeMachine  > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), sorted(examples))][-1]
2012-12-10 02:06:45

または、もう少し読みやすくするために、最後の行を分割し、関係のないリスト内包表記を取り除きます。

>>> exampleDates = [datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S") for t in examples]
>>> def beforeNow(t):
...     return currentTimeMachine > t
>>> print list(itertools.takewhile(beforeNow, sorted(exampleDates))[-1]

ただし、これは一種のばかげた方法です。あなたが本当に欲しいのは、現在の後にない例の最大値です。その英文をコードに翻訳するだけです。

>>> print max(x for x in exampleDates if x <= currentTimeMachine)

すべてをまとめてみましょう。

>>> examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
>>> exampleDates = (datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S") for t in examples)
>>> currentTimeMachine = datetime.datetime.now()
>>> print max(t for t in exampleDates if t <= currentTimeMachine)
2012-12-10 02:06:45

リストではなくジェネレーター式を使用したのは、exampleDates一度反復する必要があるものについては実際にはリストを必要としないためです。検査または繰り返し使用するために保持する場合は、括弧を角括弧に変更します。

また、「今より早い」ではなく「今より遅くない」と言ったので、 を に変更しました (つまり、今をカウントする必要があります) <<=

補足として、たまたま ISO 風のタイムスタンプがあるため、実際にはそれらを文字列として並べ替えることができます。

>>> now = datetime.datetime.now()
>>> currentTimeMachine = datetime.datetime.strftime(now, "%Y-%m-%d %H:%M:%S")
>>> print max(t for t in examples if t <= currentTimeMachine)
2012-12-10 02:06:45

'2012-12-10 02:06:45'このようにする正当な理由はありません。わずかに異なる形式のタイムスタンプを取得すると (たとえば、 before を比較するなど)、必ずバグが発生します'2012-12-10Z01:06:45'が、実際には元のコードの問題ではありません。

于 2012-12-10T03:00:17.200 に答える