1

datetime.time のリストを並べ替えて、次のような間隔を作成したいと考えています。私が持っている場合

a = [datetime.time(0,0), datetime.time(8,0), datetime.time(13,0), datetime.time(17,0)]

次に、結果は次のようになります。

c = [[datetime.time(0,0),datetime.time(8,0)], [datetime.time(8,0),datetime.time(13,0)],
[datetime.time(13,0),datetime.time(17,0)], [datetime.time(17,0),datetime.time(0,0)]]

これは単純なループを使用して実現できますが、より良い解決策が存在する場合は?

ループの使用:

>>> a=[datetime.time(0, 0), datetime.time(3, 0), datetime.time(8, 0), datetime.time(11, 0)]
>>> 
>>> r = []
>>> 
>>> for i in range(0,len(a)):
...     if i+1 < len(a):
...         r.append([a[i],a[i+1]])
...     else:
...         r.append([a[i],a[0]])
... 
>>> r
[[datetime.time(0, 0), datetime.time(3, 0)], [datetime.time(3, 0), datetime.time(8, 0)], [datetime.time(8, 0), datetime.time(11, 0)], [datetime.time(11, 0), datetime.time(0, 0)]]
>>> 

結果を変更したい場合、何を変更できるか

[[datetime.time(0, 0), datetime.time(2, 59, 59)], [datetime.time(3, 0), datetime.time(7, 59, 59)], [datetime.time(8, 0), datetime.time(10, 59, 59)], [datetime.time(11, 0), datetime.time(23, 59, 59)]]
4

5 に答える 5

8

あなたは試すことができます

a = list(zip(a[:-1], a[1:]))
a.append((a[-1], a[0])])

これにより、タプルのリストが得られます。リストのリストが必要な場合は、次のようにします

>>> a = [list(i) for i in zip(a[:-1], a[1:])]
>>> a.append([a[-1], a[0]])

( 1.リスト内包表記外と2.ZipがPython 3+でリストを返さないという事実を取って編集されたバージョン[a[-1],a[0]]

さらに別の可能性は、最初の値をリストに追加することです。

>>> tmp = a + a[0]
>>> list(zip(tmp[:,-1], tmp[1:]))

一時的なリストを作成すると主張することができます。a.append(a[0])代わりにa を実行することもできますが、最初のリストを変更することになり、問題になる可能性があります。

于 2012-09-12T12:20:42.683 に答える
5

このような範囲を作成するには、ジェネレーターを試してみてください。

def make_ranges(lst):
    max_idx = len(lst) - 1
    for i,item in enumerate(lst):
        yield [item, lst[i+1 if i != max_idx else 0] ]

キーワード引数をいじってmake_ranges、周期的であるかどうか、周期的である場合は、最初または最後にラップアラウンドを含めるかどうかを指定できます。

次に、範囲を作成できます。

a = [1,2,3,4,5,6,7,8]
b = list(make_ranges(a))
print(b == [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,8],[8,1]]) #True
于 2012-09-12T12:55:35.977 に答える
3

もう 1 つのオプション1をワンライナーとして: ただし、最後のペアと最初のペアを別のステップで追加する必要がないように、本当に非 Pythonic な式(imho) を使用します。

>>> [list(i) for i in zip(a, a[1:]+[a[0]])]
[[datetime.time(0, 0), datetime.time(8, 0)],
 [datetime.time(8, 0), datetime.time(13, 0)],
 [datetime.time(13, 0), datetime.time(17, 0)],
 [datetime.time(17, 0), datetime.time(0, 0)]]

上記のPierre-GMのソリューションに触発された1zipつの方法。

参考までに、私はこれよりも私の最初の答えまたはピエールのどちらかを好みます


質問の 2 番目の部分の編集/更新: timedeltas を 1 つの式で実行するには (ただし、代わりにこれを別のステートメントに分割してはならない理由はわかりません...):

>>> [[i, (datetime.datetime(101, 1, 1, j.hour, j.minute, j.second) -
...       datetime.timedelta(seconds=1)
...      ).time()
...  ] for i,j in zip(a, a[1:]+[a[0]])
... ]
[[datetime.time(0, 0), datetime.time(7, 59, 59)],
 [datetime.time(8, 0), datetime.time(12, 59, 59)],
 [datetime.time(13, 0), datetime.time(16, 59, 59)],
 [datetime.time(17, 0), datetime.time(23, 59, 59)]]
于 2012-09-12T13:30:14.620 に答える
2

「単純なループ」ではない場合、リスト内包表記はどうですか? お気に入り:

>>> b = [[a[x], a[x+1]] for x in range(0, len(a)-1)] + [[a[-1], a[0]]]
>>> b
[[datetime.time(0, 0), datetime.time(8, 0)],
 [datetime.time(8, 0), datetime.time(13, 0)],
 [datetime.time(13, 0), datetime.time(17, 0)],
 [datetime.time(17, 0), datetime.time(0, 0)]]
于 2012-09-12T12:24:20.363 に答える