Ordering an un-ambiguous scrambled date
Wrong bounds

Your filters on your day/month aren't right:

day = [i for i in (x,y,z) if i &lt; 31]
month = list(set(i for i in (x,y,z) if i &lt; 12))


31 is a valid day and 12 is a valid month, so those should be &lt;=. Additionally, you're not excluding negative numbers - so you'll want 1 &lt;= i &lt;= 31 for the first filter and 1 &lt;= i &lt;= 12 for the second.

Dealing with the tuple

Since just about everywhere you deal with (x,y,z) as a tuple, I would just keep it as a tuple the whole way and not unpack it. You only unpack it to check the length, so we can just make that check explicit. Also, if I passed in something like 1/2/3/4/5, you'd tell me that my date was too short, so this can get both right:

elems = un_ambiguous_date.split('/')
if len(elems) != 3:
    raise ValueError("The date is too {}, format should be X/Y/Z".format(
        'short' if len(elems) &lt; 3 else 'long'))

try:
    elems = map(int, elems)
except ValueError:
    raise ...

day = [i for i in elems if 1 &lt;= i &lt;= 31]    
# etc.


The last join

Instead of:

return '/'.join(map(str, (day[0], month[0], year[0])))


I would just use format:

return '{}/{}/{}'.format(day[0], month[0], year[0])


It's shorter and more readable. 

Combine the last two checks

I would write a helper function that returns the first element of a single-element list:

def front(lst):
    if not lst:
        raise ValueError("The date cannot be valid")
    if len(lst) &gt; 1:
        raise ValueError("Ambiguous date was given")

    return lst[0]


And then you can just write:

return '{}/{}/{}'.format(front(day), front(month), front(year))