У вас есть два вопроса: один из заголовка и вопрос, скрывающийся за ним.На первый ответ:
First/@ list
На второй, подсчитывающий количество прогонов 1, отвечали много раз, но это решение
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &
составляет около 50%.быстрее, чем решение Леонида.Заметьте, что я увеличил длину списка тестов для лучшего выбора времени:
largeTestList = RandomInteger[{0, 1}, {10000000}];
Count[Split[largeTestList], {1 ..}] // AbsoluteTiming
Count[Split[largeTestList][[All, 1]], 1] // AbsoluteTiming
Total[Clip[Differences@#, {0, 1}]] + First[#] &@ largeTestList // AbsoluteTiming
(Tr@Unitize@Differences@# + Tr@#[[{1, -1}]])/2 &@ largeTestList // AbsoluteTiming
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
Out[680]= {3.4361965, 2498095}
Out[681]= {2.4531403, 2498095}
Out[682]= {0.2710155, 2498095}
Out[683]= {0.2530145, 2498095}
Out[684]= {0.1710097, 2498095}
После атаки компиляции Леонида я собирался бросить полотенце, но я заметил возможную оптимизацию, поэтому битва продолжается... [Мистер Волшебник, мы с Леонидом должны быть брошены в тюрьму за нарушение спокойствия на ЮЗ]
runsOf1Cbis =
Compile[{{lst, _Integer, 1}},
Module[{r = Table[0, {Length[lst] - 1}], i = 1, ctr = First[lst]},
For[i = 2, i <= Length[lst], i++,
If[lst[[i]] == 1 && lst[[i - 1]] == 0, ctr++; i++]];
ctr], CompilationTarget -> "C", RuntimeOptions -> "Speed"]
largeTestList = RandomInteger[{0, 1}, {10000000}];
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
runsOf1C[largeTestList] // AbsoluteTiming
runsOf1Cbis[largeTestList] // AbsoluteTiming
Out[869]= {0.1770101, 2500910}
Out[870]= {0.0960055, 2500910}
Out[871]= {0.0810046, 2500910}
Результаты меняются, но я получаю улучшение от 10 до 30%.
Оптимизация может быть трудно определить, но это дополнительный i++
, если тест {0,1} пройден успешно.Вы не можете иметь два из них в последовательных местоположениях.
И, здесь, оптимизация оптимизации Леонида моей оптимизации его оптимизации (я надеюсь, что это не будет тянуть, или яЯ собираюсь перенести переполнение стека):
runsOf1CDitto =
Compile[{{lst, _Integer, 1}},
Module[{i = 1, ctr = First[lst]},
For[i = 2, i <= Length[lst], i++,
If[lst[[i]] == 1, If[lst[[i - 1]] == 0, ctr++];
i++]];
ctr], CompilationTarget -> "C", RuntimeOptions -> "Speed"]
largeTestList = RandomInteger[{0, 1}, {10000000}];
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
runsOf1C[largeTestList] // AbsoluteTiming
runsOf1Cbis[largeTestList] // AbsoluteTiming
runsOf1CAlt[largeTestList] // AbsoluteTiming
runsOf1CDitto[largeTestList] // AbsoluteTiming
Out[907]= {0.1760101, 2501382}
Out[908]= {0.0990056, 2501382}
Out[909]= {0.0780045, 2501382}
Out[910]= {0.0670038, 2501382}
Out[911]= {0.0600034, 2501382}
К счастью для меня, у Леонида была лишняя инициализация в коде, которую можно было удалить.