Comparison of values in python Tuples list 3.x

Asked

Viewed 812 times

2

My doubt is how I can interact on this list to make comparisons between values.

def trocar(vals, posX, posY):
    temp = vals[posX]
    vals[posX] = vals[posY]
    vals[posY] = temp
    return None


def ordenar(valores):
    tamanho = len(valores) - 1
    troquei = True
    while troquei:
       troquei = False
       for i in range(tamanho):
          if valores[i] > valores[i + 1]:
            trocar(valores, i, i + 1)
            troquei = True
    tamanho -= 1
return valores


lista= [('Ana', 30, 6.69), ('João', 25, 6.11), ('Pedro', 30, 6.69),    ('Maria', 28, 5.45), ('Thiago', 40, 5.45), ('Raquel', 26, 10.0)]

x=ordenar(lista)
print(x) # [('Ana', 30, 6.69), ('João', 25, 6.11), ('Maria', 28, 5.45), ('Pedro', 30, 6.69), ('Raquel', 26, 10.0), ('Thiago', 40, 5.45)]

My intention is to print the names in order according to the values:

  1. The first order is by average.
  2. If one of the averages is equal step to age
  3. If the average and the age are equal step to alphabetical order of the names

In the above code only one of the objectives was achieved; pick up the names in alphabetical order

  • This friend is from college, and I like this method of teaching them, the programs are made with the least possible use of methods and ready api, everything is at hand, I can’t use Sorted, Sort or any other python api method, I have to do in the same bean and I have to use the ordination functions I posted (def change and def order),

1 answer

4


In your example a list of tuples is being sorted. In the current logic you are using the operator > to compare two tuples. This makes sense since a tuple is a sequence, and as - free translation from - python documentation:

Sequences are compared lexicographically by comparing corresponding elements. [...] Collections that support order comparisons are ordered according to their unequal first elements (for example, [1,2,x] <= [1,2,y] has the same value as x <= y).

Knowing this, the trick to order a list of tuples correctly is to rearrange the elements of each tuple according to its comparison criteria. In case, you want to turn a tuple (nome, idade, media) on a tuple (media, idade, nome) for comparison purposes.

Assuming that the averages should be sorted downwards and the other elements in ascending order the implementation would be like this:

def rearranjar_tupla(tupla):
    return (-tupla[2], tupla[1], tupla[0])
    
def ordenar(valores):
    tamanho = len(valores) - 1
    troquei = True
    while troquei:
       troquei = False
       for i in range(tamanho):
          if rearranjar_tupla(valores[i]) > rearranjar_tupla(valores[i + 1]):
            trocar(valores, i, i + 1)
            troquei = True
    tamanho -= 1
    return valores 

See it working on Ideone

If the averages should also be sorted upwards just invert the positions of the tuple with Extended Slice:

def rearranjar_tupla(tupla):
    return tupla[::-1]

See it working on Ideone

However, it is important to emphasize that, in addition to learning purposes, reinventing the wheel is not usually a good idea. In addition to the extra code, this basic sorting algorithm (Bubble Sort) is expensive from the point of view of Asymptotic Complexity (O(n²)) and very bad from the point of view of cache hits and memory management (multiple copies and swaps unnecessary put pressure on Garbage Collector).

The standard Python API sorting mechanisms are worth a fairly robust algorithm called Timsort, able to order collections efficiently, with Asymptotic Complexity O(n*log(n)) worst-case.

Using the standard Python library we can replace all the code from the first example with a single line of code:

lista.sort(key=lambda x: (-x[2], x[1], x[0]))

See it working on Ideone


Sources

  1. Soen - How does tuple comparison work in Python?
  2. The Python Language Reference - Value comparisons
  3. What’s New in Python 2.3 - Extended Slices
  4. Sorting HOW TO
  5. Wikipedia - Timsort
  • Thanks friend for the help, this tip will help me a lot, now I will try to make an implementation to show the classification of students according to the criteria, I think I will have to compare the lists of tuples generated , I will generate 3 lists, one sorted by media , another ordered by age and another ordered by name.

  • Hi Bruno, unless I’m mistaken I believe that the classification is the first example (higher averages first, unpaired by underage and finally alphabetical order).

  • That Anthony, first it is made the comparison with the average if the averages are equal the tiebreaker is by age if it continues equal here comes the tiebreaker by name and in the end I print only the names of the students by order of classification.

Browser other questions tagged

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