2015-10-02 16 views
7

私は、日付オブジェクトの辞書のリストを持っている:辞書のリストを条件別に簡略化するにはどうすればいいですか?

{ "begin" :date object1, "end" : date object2 } 
.... 
{ "begin" :date object3, "end" : date object4 } 

私は条件によって、このリストを簡素化したい:それを行うにはどのように

if cur.end == next.begin - datetime.timedelta(seconds=1)) 
    cur.end = next.end 
    delete next 

+0

そして、どのようにあなたが最後のものを単純化するのでしょうか? –

+1

http://stackoverflow.com/questions/5434891/iterate-a-list-as-pair-current-next-in-python –

+1

これは多くのお手伝いをします。また、そのリストのコピーを反復すると、リストを反復処理している間に次のものを削除することはできません; –

答えて

1

コードを単純なものにするためにdatetimeオブジェクトの代わりに整数を使用しますが、必要に応じて変更するのは簡単です。 反復処理中にコレクションから項目を削除すると、繰り返し処理が中断されますので、2番目のリストを使用するか(メモリーを大量に消費する可能性があります)、削除する代わりに要素を置き換えます。あなたの要素は辞書なので、削除する要素をNoneに置き換えるのは安全だと思っていました。最後にNonesをフィルタリングするだけです。

l=[ 
{ "b" : 1, "e" : 2}, 
{ "b" : 3, "e" : 5}, 
{ "b" : 6, "e" : 7}, 
{ "b" : 10, "e" : 12}, 
{ "b" : 13, "e" : 20} 
] 

for i in xrange(len(l) - 1): 
    cur = l[i] 
    if not cur: 
     continue 
    next = l[i + 1] 
    if cur["e"] == next["b"] - 1: 
     cur["e"] = next["e"] 
     l[i+1] = None 

l = filter(None, l) 
print l 

最初のバージョンでは完全には満たされないため、これ以上の時間間隔をマージできなくなるまで手順を繰り返します。 これは非効率的で、おそらく最も非平凡なコードですが、それは仕事です。

changed = True 
while changed: 
    changed = False 
    l = filter(None, l) 
    for i in xrange(len(l) - 1): 
     cur = l[i] 
     if cur is None: 
      continue 
     next = l[i + 1] 
     if cur["e"] == next["b"] - 1: 
      cur["e"] = next["e"] 
      l[i+1] = None 
      changed = True 

l = filter(None, l) 
print l 
+0

結果は[{'b':1、 'e':7}、{'b':10、 'e {b ':1、' e ':5}、{' b ':6、' e ':7}ではなく、':20 '、{' b ':22、' e ':24} {'b':22、 'e':24}] – Bdfy

+0

@Bdfy {'b':22、 'e':24 } から来る。私は私の出力でそれを見ない – user1514631

1

などは他の回答で説明し、あなたはそれを反復しながら、それは問題の多くにつながることができ、リストから要素を削除しないでください。完全に新しいリストがあろう作成する別の方法 -

import datetime 
lisdic = [] #list of dictionaries 
prev = None 
result = [] 
for i in lisdic: 
    if not prev: 
     prev = i 
    elif prev['end'] == i['begin'] - datetime.timedelta(seconds=1): 
     prev['end'] = i['end'] 
    else: 
     result.append(prev) 
     prev = i 
if prev: 
    result.append(prev) 

また、これは、(以下の例は、デモでリストの最初の3つの辞書である)複数の辞書を横切って同様の間隔を扱うことになります。

デモ -

>>> import datetime 
>>> lisdic = [{"begin":datetime.datetime(2015,10,2,10,0,0),"end":datetime.datetime(2015,10,2,10,30,0)}, 
... {"begin":datetime.datetime(2015,10,2,10,30,1),"end":datetime.datetime(2015,10,2,11,0,0)}, 
... {"begin":datetime.datetime(2015,10,2,11,0,1),"end":datetime.datetime(2015,10,2,12,0,0)}, 
... {"begin":datetime.datetime(2015,10,3,10,0,0),"end":datetime.datetime(2015,10,3,10,30,0)}, 
... {"begin":datetime.datetime(2015,10,3,11,0,0),"end":datetime.datetime(2015,10,3,11,30,0)}, 
... {"begin":datetime.datetime(2015,10,4,12,0,0),"end":datetime.datetime(2015,10,2,12,10,0)}] 
>>> prev = None 
>>> result = [] 
>>> for i in lisdic: 
...  if not prev: 
...   prev = i 
...  elif prev['end'] == i['begin'] - datetime.timedelta(seconds=1): 
...   prev['end'] = i['end'] 
...  else: 
...   result.append(prev) 
...   prev = i 
... 
>>> 
>>> if prev: 
...  result.append(prev) 
... 
>>> pprint.pprint(result) 
[{'begin': datetime.datetime(2015, 10, 2, 10, 0), 
    'end': datetime.datetime(2015, 10, 2, 12, 0)}, 
{'begin': datetime.datetime(2015, 10, 3, 10, 0), 
    'end': datetime.datetime(2015, 10, 3, 10, 30)}, 
{'begin': datetime.datetime(2015, 10, 3, 11, 0), 
    'end': datetime.datetime(2015, 10, 3, 11, 30)}, 
{'begin': datetime.datetime(2015, 10, 4, 12, 0), 
    'end': datetime.datetime(2015, 10, 2, 12, 10)}]