Exercise in the ordering of tuples

Asked

Viewed 624 times

0

I’m getting beat up in a Python exercise. He asks for the following:

Create a function that:

  • Receive a list of tuples (data), an integer (key, zero by default equal) 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(), who makes comparisons between two arguments and returns -1 if the first element is larger , 0 (zero) if they are equal to or 1 if the latter is larger. This function is used by the ordering routine, 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)

Exit:

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

Doubts:

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

I would like to solve by taking advantage of the functions sorted() and cmp() and not implementing ordering from scratch (I think this is the intention of the exercise as well). I understand that I should create a function _cmp() based on cmp() and receiving as optional parameters chave and reverso. But the example calls the function so sorted(dados, _cmp) and I understand that sorted() will call the function internally _cmp() passing two parameters only (the two elements that should be compared). I even tried to solve by passing the two optional parameters to _cmp but that doesn’t make much sense and I stopped there... it was 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)

Exit:

[(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__'
  • Why not just do: https://repl.it/repls/StarkCrowdedTriangle? As for the error is why you are calling _cmp(0, True) in this case, and you can’t do x[chave] because the way you built it x = 0, and you can’t ask for the input of an integer as if it were an eternal (obviously (; )

  • @Miguel I believe that the material I am following did not provide the necessary subsidy to resolve the exercise. Did not teach how to create Holds, for example, nor to use a function as a key (key) of sorted(). His code helped to advance the exercise though, showing that sorted() is the function it can receive reverse and not _cmp(). If there is no way to solve the exercise with the subsidy I have I will disregard it (and be a little behind with the material). Please confirm for me that this code is the easiest way to do, and if you want to put it in a reply I will accept it.

  • It’s the pythonic way of doing it, it’s how you’re going to do it maybe in the next phase, if you develop real world projects in python it will be like this. But I do not know if it is necessary to do the exercise as you pointed out, this more 'from scratch', so I did not put as an answer, I could not solve the way you wanted. And as for the mistake I hope to have helped

1 answer

1


When to the "equal default zero", I think the word "equal" actually remained there. As for the function cmp, it has been removed from Python 3 and, even if your question cites version 2.7, I see no reason to actually study it or even use such a version. I strongly recommend that you study Python version 3 directly.

The easiest way I see to solve this problem is to use the function sorted together with the function itemgetter module operator.

from operator import itemgetter

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

Thus, if defined dados as:

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 of an object passed via parameter to that second function. For example, do f = itemgetter(5) and then call f(x), the value of x[5].

See working on Repl.it | Ideone

Browser other questions tagged

You are not signed in. Login or sign up in order to post.