<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Dual Pivot Quicksort
The function sort takes a list L that is to be sorted and returns the sorted list.
It implements dual pivot quicksort and uses the first and the last element as pivots p1 and p2.
Step1:  The function partition receives three arguments
<ASSISTANT_TASK:>
Python Code:
def sort(L):
    if len(L) <= 1:
        return L
    x, y, R    = L[0], L[-1], L[1:-1]
    p1, p2     = min(x, y), max(x, y)
    L1, L2, L3 = partition(p1, p2, R)
    if p1 == p2:
        return sort(L1) + [p1] + L2 + [p2] + sort(L3)
    else:
        return sort(L1) + [p1] + sort(L2) + [p2] + sort(L3)
Explanation: Dual Pivot Quicksort
The function sort takes a list L that is to be sorted and returns the sorted list.
It implements dual pivot quicksort and uses the first and the last element as pivots p1 and p2.
End of explanation
def partition(p1, p2, L):
    if L == []:
        return [], [], []
    x, *R      = L
    R1, R2, R3 = partition(p1, p2, R)
    if x < p1:
        return [x] + R1, R2, R3
    if x <= p2:
        return R1, [x] + R2, R3
    else:
        return R1, R2, [x] + R3
partition(5, 13, [1, 19, 27, 2, 5, 6, 4, 7, 8, 5, 8, 17, 13])
sort([1, 19, 27, 2, 5, 6, 4, 7, 8, 5, 8, 17, 13])
Explanation: The function partition receives three arguments:
* p1 and p2 are comparable objects taken from some list that is to be sorted.
  Furthermore p1 &lt;= p2.
* L is a list of comparable elements. 
The function partions the list into three sublists.  Mathematically, we have:
$$ \texttt{partition}(p_1, p_2, L) = \bigl\langle[x \in L \mid x < p_1],\; [x \in L \mid p_1 \leq x \leq p_2],\; [x \in L \mid p_2 < x]\bigr\rangle $$
End of explanation
<END_TASK>