Tuple ordering exercise

0

I'm catching up on a Python exercise. It asks for the following:

  

Create a function that:

     
  • Get a list of tuples (data), an integer (key, zero by default) and a boolean (reverse, false by default).
  •   
  • Return data sorted by the item indicated by the key and in descending order if reverse is true.
  •   

The knowledge I have to solve it is the knowledge of how to create functions and the following explanation:

  

The interpreter has defined some builtin functions, including    sorted() , which orders sequences, and cmp() , which makes comparisons between   two arguments and returns -1 if the first element is greater, 0   (zero) if they are equal or 1 if the last one is greater. This function is used   by the sort order, a behavior that can be modified.

     

Example:

dados = [(4, 3), (5, 1), (7, 2), (9, 0)]

# Comparando pelo último elemento
def _cmp(x, y):
    return cmp(x[-1], y[-1])

print 'Lista:', dados

# Ordena usando _cmp()
print 'Ordenada:', sorted(dados, _cmp)

Output:

Lista: [(4, 3), (5, 1), (7, 2), (9, 0)]
Ordenada: [(9, 0), (5, 1), (7, 2), (4, 3)]

Questions:

I do not understand the phrase "zero by default", this "equal" there seems to be left in the sentence.

I would like to solve by taking advantage of the functions sorted() and cmp() and not implementing zero ordering (I think this is the intention of the exercise too). I understand that I should create a _cmp() function based on cmp() and receive as optional parameters chave and reverso . But the example calls the function so sorted(dados, _cmp) and I understand that sorted() will internally call the _cmp() function by passing two parameters only (the two elements to be compared). I even tried to solve by passing the two optional parameters to _cmp but that does not make much sense and I packed there ... it looked like this:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

def ordenar(dados, chave = 0, reverso = False):
    return (dados, _cmp(chave, reverso))

def _cmp(x, y, chave = 0, reverso = False):
    if reverso == False:
        return cmp(x[chave], y[chave])
    else:
        return cmp(y[chave], x[chave])

dados = [(4, 3), (5, 1), (7, 2), (9, 0)]

print dados
print ordenar(dados, 1, True)

Output:

[(4, 3), (5, 1), (7, 2), (9, 0)]
Traceback (most recent call last):
  File "apl.py", line 16, in <module>
    print ordenar(dados, 1, True)
  File "apl.py", line 5, in ordenar
    return (dados, _cmp(chave, reverso))
  File "apl.py", line 9, in _cmp
    return cmp(x[chave], y[chave])
TypeError: 'int' object has no attribute '__getitem__'
    
asked by anonymous 10.03.2018 / 17:14

1 answer

1

When " zero by default equal ", I think the word "equal" is actually left there. As for the cmp function, it was removed from Python 3, and even if your question quotes version 2.7, I see no reason to actually study it or even use that version. I strongly recommend that you go straight to Python version 3.

The easiest way I can solve this problem is to use the sorted function in conjunction with the itemgetter function of the operator module.

from operator import itemgetter

def ordenar(dados, chave = 0, reverso = False):
  return sorted(dados, key=itemgetter(chave), reverse=reverso)

So if you set dados to:

dados = [(4, 3), (5, 1), (7, 2), (9, 0)]

You have the results:

>>> ordenar(dados)
[(4, 3), (5, 1), (7, 2), (9, 0)]

>>> ordenar(dados, chave=1)
[(9, 0), (5, 1), (7, 2), (4, 3)]

>>> ordenar(dados, chave=1, reverso=True)
[(4, 3), (7, 2), (5, 1), (9, 0)]

The function itemgetter returns a function that accesses a given key from an object passed via parameter to that second function. For example, doing f = itemgetter(5) and then calling f(x) will return the value of x[5] .

See working at Repl.it | Ideone

    
12.03.2018 / 16:59