I feel describing initializer_list as lightweight misses the point.
The initializer_list is (by necessity) handled by the compiler. Its definition does not include memory management or ownership, nor does it have a useful (non-blank) constructor, nor must it conform to any particular layout. The standard suggests its representation is basically pair of pointers (begin and end):
An object of type initializer_list provides access to an array of objects of type const E. [Note: A pair of pointers or a pointer plus a length would be obvious representations for initializer_list.]
And we can see elsewhere in the standard that initializer_list is generally used as if something had happened, but does not actually require anything concrete::
An object of type std::initializer_list is constructed from an initializer list as if the implementation generated and materialized a prvalue of type “array of N const E”
Allocation, initialisation and teardown of members, if required, is added by the compiler, and has nothing to do with the list itself.
Contrast this with a vector that can be modified on demand, performs memory management, and actually owns the objects inside the array, mandating that they exist in the heap.
As to which to use, it depends on the circumstances, in the example above I'd use the initializer list, since it would seem simpler. However I'd believe a vector could be more efficient if I were moving contents into my own vector (and I could therefore simply use std::move), or if I believed the user would likley already be starting out with their own vector, and I could therefore avoid an unnecessary intermediate.