def _orderedSelect(self, selection, orderedBy, orderDirection):
        """
        The variant of the selection (as below) that also includes the
        sorting. Because that is much less efficient, this is separated into
        a distinct method that is called only if necessary. It is called
        from the :meth:`select` method.

        Because order can be made on variables that are not part of the final
        selection, this method retrieves a *full* binding from the result to
        be able to order it (whereas the core :meth:`select` method retrieves
        only the selected bindings from the result). The full binding is an
        array of (binding) dictionaries; the sorting sorts this array by
        comparing the bound variables in the respective dictionaries. Once
        this is done, the final selection is done.

        :param selection: Either a single query string, or an array or tuple
            of query strings.
        :param orderBy: either a function or a list of strings (corresponding
            to variables in the query). If None, no sorting occurs on the
            results. If the parameter is a function, it must take two
            dictionary arguments (the binding dictionaries), return -1, 0,
            and 1, corresponding to smaller, equal, and greater, respectively.
        :param orderDirection: if not None, then an array of integers of the
            same length as orderBy, with values the constants ASC or DESC
            (defined in the module). If None, an ascending order is used.
        :return: selection results as a list of tuples
        :raise SPARQLError: invalid sorting arguments
        """
        fullBinding = self._getFullBinding()

        if type(orderedBy) is types.FunctionType:
            _sortBinding = orderedBy
        else:
            orderKeys = _variablesToArray(orderedBy,"orderBy")
            # see the direction
            oDir = None # this is just to fool the interpreter's error message

            if orderDirection is None :
                oDir = [True for i in xrange(0, len(orderKeys))]

            elif type(orderDirection) is types.BooleanType:
                oDir = [orderDirection]

            elif type(orderDirection) is not types.ListType \
                and type(orderDirection) is not types.TupleType:
                raise SPARQLError(
                    "'orderDirection' argument must be a list")

            elif len(orderDirection) != len(orderKeys) :
                raise SPARQLError(
                    "'orderDirection' must be of an equal length to 'orderBy'")

            else :
                oDir = orderDirection

            def _sortBinding(b1, b2):
                """
                The sorting method used by the array sort, with return values
                as required by the Python run-time
                The to-be-compared data are dictionaries of bindings.
                """

                for i in xrange(0, len(orderKeys)):
					# each key has to be compared separately. If there is a
                    # clear comparison result on that key then we are done,
                    # but when that is not the case, the next in line should
                    # be used
                    key = orderKeys[i]
                    direction = oDir[i]
                    if key in b1 and key in b2:
                        val1 = b1[key]
                        val2 = b2[key]
                        if val1 != None and val2 != None:
                            if direction:
                                if val1 < val2:
                                    return -1
                                elif val1 > val2:
                                    return 1
                            else:
                                if val1 > val2:
                                    return -1
                                elif val1 < val2:
                                    return 1

                return 0

        # get the full Binding sorted

        try:
            keyfunc = functools.cmp_to_key(_sortBinding)
            fullBinding.sort(key=keyfunc)

        except __HOLE__:
            # Python < 2.7
            fullBinding.sort(cmp=_sortBinding)

        # remember: _processResult turns the expansion results (an array of
        # dictionaries) into an array of tuples in the right, original order
        retval = _processResults(selection,fullBinding, self._getAllVariables())

        return retval
dataset/ETHPy150Open RDFLib/rdfextras/rdfextras/sparql/query.py/Query._orderedSelect