The Contents section says what goes into a basic filter, but nothing in the BIP says that an item appearing more than once is only included once. Set Construction describes L as "a vector of N raw items", so building the filter from the text alone keeps duplicates.
That gives a different result from the test vectors. Block 926485 in bip-0158/testnet-19.json ("Duplicate pushdata 913bcc2b...") spends several outputs with the same script. Keeping every item gives N=17 and a filter and filter header that don't match. Removing duplicates gives N=9, which matches the vector. All other vectors come out the same either way.
Bitcoin Core (GCSFilter::ElementSet is a std::unordered_set) and btcd (gcs/builder collects into a map) both dedupe, so this only writes down what implementations already do.