これがもう少し効率的な解決策です(申し訳ありませんがJavaScriptです)。重要なのは、長さを1回だけ保存することです。コードでは、長さが1つ増えるたびに計算を行います "startLength [start] = 1 +cnt--start"。
「ifprevious==1 and r == 1」の代わりに、条件「if previous == 0 and r==1」を使用します。計算の量を減らしますが、最後のケースをキャッチするために、forループの後に「ifr==1」を追加する必要もあります。
var test=[0,1,1,1,0,0,0,1,1,0,0,1,0];
function runs(arr) {
var result = {};
var start = 0;
var previous = 0;
var cnt = 0;
var r = 0;
for(; cnt<arr.length; cnt++) {
var r = arr[cnt];
if(r == 1 && previous == 0)
start = cnt;
if(r == 0 && previous == 1)
result[start] = cnt - start;
previous = r;
}
if(r == 1)
result[start] = cnt - start;
return result;
}
var result = runs(test);
for(var start in result)
console.log("start " + start + " length " + result[start]);
編集2これは、groupby関数(現在、この質問に対する一番の答え)の使用が大幅に遅いことを示すPythonベンチマークです。
from itertools import groupby
from operator import itemgetter
import random
import time
lst = [ 1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0]
def makeList(size):
random.seed()
return [random.randint(0,1) for r in xrange(size)]
def runs1(lst, showOutput):
startLength = {}
for k,v in groupby(enumerate(lst),key=itemgetter(1)):
if k:
v = list(v)
startLength[v[0][0]] = v[-1][0] + 1 - v[0][0]
if showOutput == True:
for s,l in startLength.iteritems():
print s,l
def runs2(lst, showOutput):
previous = 0
cnt = 0
startLength = {}
for r in lst:
if previous == 0 and r == 1:
start = cnt
if previous == 1 and r == 0:
startLength[start] = cnt - start
previous = r
cnt += 1
if r == 1:
startLength[start] = cnt - start
if showOutput == True:
for s,l in startLength.iteritems():
print s,l
testList = makeList(10)
print "slow version"
runs1(testList, True)
print "fast version"
runs2(testList, True)
benchmarkList = makeList(10000)
start = time.time()
runs1(benchmarkList, False)
print "slow ", time.time() - start
start = time.time()
runs2(benchmarkList, False)
print "fast ", time.time() - start
start = time.time()
runs1(benchmarkList, False)
print "slow ", time.time() - start
start = time.time()
runs2(benchmarkList, False)
print "fast ", time.time() - start
start = time.time()
runs1(benchmarkList, False)
print "slow ", time.time() - start
start = time.time()
runs2(benchmarkList, False)
print "fast ", time.time() - start