Best way to represent a dynamic list

An idea using subspaces is the next. A schema is (uint8, ...uint8).

(0): Empty (Skipped)
(1): First value <- Insert the third value before here.
(2): Empty (Skipped)
(3): Second value <- Insert the fourth value before here.
(4): Empty (Skipped)
.
.
.
(0, 127): Third value <- Insert the fifth value before here.
(1): First value
(2): Fourth value <- Insert the sixth value before here.
(3): Second value
(4): Empty (Skipped)
.
.
.
(0, 125): Fifth value
(0, 127): Third value
(1): First value
(1, 127): Sixth value
(2): Fourth value
(3): Second value
(4): Empty (Skipped)
.
.
.

The order is (0, 125), (0, 127), (1), ....

Any better efficient ways?

Fix uint8 to uint64. Skip size could be larger.

Maybe byte string is better. Where {0} is b'\x00' ([]{0} in go).

{0, 125}: Fifth value
{0, 127}: Third value
{1}: First value
{1, 127}: Sixth value
{2}: Fourth value
{3}: Second value
{4}: Empty (Skipped)
.
.
.

The order is {0, 125}, {0, 127}, {1}, ....

Now I feel (uint64, bytes) or (bytes, bytes) is better for large lists and few(0-1000) insertions per root node. Any less constrained representations?