def taper(self, operator: PauliSumOp) -> OperatorBase:
        """
        Taper an operator based on the z2_symmetries info and sector defined by `tapering_values`.
        The `tapering_values` will be stored into the resulted operator for a record.

        Args:
            operator: the to-be-tapered operator.

        Returns:
            If tapering_values is None: [:class`PauliSumOp`]; otherwise, :class:`PauliSumOp`
        Raises:
            OpflowError: Z2 symmetries, single qubit pauli and single qubit list cannot be empty
        """
        if not self._symmetries or not self._sq_paulis or not self._sq_list:
            raise OpflowError(
                "Z2 symmetries, single qubit pauli and " "single qubit list cannot be empty."
            )

        if operator.is_zero():
            logger.warning("The operator is empty, return the empty operator directly.")
            return operator

        for clifford in self.cliffords:
            operator = cast(PauliSumOp, clifford @ operator @ clifford)

        if self._tapering_values is None:
            tapered_ops_list = [
                self._taper(operator, list(coeff))
                for coeff in itertools.product([1, -1], repeat=len(self._sq_list))
            ]
            tapered_ops: OperatorBase = ListOp(tapered_ops_list)
        else:
            tapered_ops = self._taper(operator, self._tapering_values)

        return tapered_ops
    def taper(self, operator: PauliSumOp) -> OperatorBase:
        """
        Taper an operator based on the z2_symmetries info and sector defined by `tapering_values`.
        The `tapering_values` will be stored into the resulted operator for a record.

        Args:
            operator: the to-be-tapered operator.

        Returns:
            If tapering_values is None: [:class`PauliSumOp`]; otherwise, :class:`PauliSumOp`
        Raises:
            OpflowError: Z2 symmetries, single qubit pauli and single qubit list cannot be empty
        """
        if not self._symmetries or not self._sq_paulis or not self._sq_list:
            raise OpflowError(
                "Z2 symmetries, single qubit pauli and single qubit list cannot be empty."
            )

        # If the operator is zero then we can skip the following. We still need to taper the
        # operator to reduce its size i.e. the number of qubits so for example 0*"IIII" could
        # taper to 0*"II" when symmetries remove two qubits.
        if not operator.is_zero():
            for clifford in self.cliffords:
                operator = cast(PauliSumOp, clifford @ operator @ clifford)

        if self._tapering_values is None:
            tapered_ops_list = [
                self._taper(operator, list(coeff))
                for coeff in itertools.product([1, -1], repeat=len(self._sq_list))
            ]
            tapered_ops: OperatorBase = ListOp(tapered_ops_list)
        else:
            tapered_ops = self._taper(operator, self._tapering_values)

        return tapered_ops