OFF - Is it possible to print a list value by passing its index?

Asked

Viewed 69 times

1

In the code below I,when I come out of the while,I print the athlete jumps data, along with the average of the same. In the loop for,I print out all the jumps of the athlete, 'Cause I wanted to do something like this:

First jump:5.8

Second jump:5.7

Third jump: 6.1

And so on and so on

distancia =[]
salto = 0

while nome != '':
    nome = input('Insira o nome do atleta:')
    nomes.append(nome)
    if nome == '':
        break;
    for i in range(1,6):
        salto = float(input(f'Informe a distância do {i}º salto do atleta:'))
        distancia.append(salto)
        media = sum(distancia)/len(distancia)
print(f'Atleta:{nome}')
for i in distancia:
    print(i)
print('Resultado final')
print(f'Saltos:{distancia}')
print(f'Média dos saltos:{media}')```

2 answers

1

If you want exactly the texts "First", "Second", etc., there is no direct way - at least natively - to get it. The way is to build the texts yourself, or use an external module.

If you choose to build texts manually, an alternative would be to have a list of options:

distancia = # código para preencher a lista é igual ao seu

ordinais = ['Primeiro', 'Segundo', 'Terceiro', 'Quarto', 'Quinto' ]
for i, salto in enumerate(distancia):
    print(f'{ordinais[i]} salto: {salto}')

Another option, as indicated in the comments, is to use zip to browse both lists simultaneously:

for ordinal, salto in zip(ordinais, distancia):
    print(f'{ordinal} salto: {salto}')

The detail is that zip ends when the shortest of the lists ends, so you have to ensure that there are enough texts on ordinais so that no element of distancia stay out (actually, in the first option you also have to ensure this, otherwise a jump will be without the corresponding text).

So another more general option is to use itertools.zip_longest, which is similar to zip, but iterates to the end of the largest list, and the missing elements of the smallest list are, by default, equal to None. In case you have more jumps than text, you could put the suffix º, as suggested by the other reply (but if you have the text, use it):

distancia = ...
ordinais = ['Primeiro', 'Segundo', 'Terceiro', 'Quarto', 'Quinto' ]

from itertools import zip_longest

for i, (ordinal, salto) in enumerate(zip_longest(ordinais, distancia), start=1):
    if salto is None: # não há mais saltos, pare o loop
        break
    if ordinal is None: # não há mais textos, usa o número e o sufixo º
        ordinal = f'{i}º'
    print(f'{ordinal} salto: {salto}')

But this option is kind of limited, because if it is possible a very large amount of jumps, the list ordinais will become huge.

In this case, another option is to use some external module. An alternative is the num2words:

from num2words import num2words

for i, salto in enumerate(distancia, start=1):
    print(f'{num2words(i, to="ordinal", lang="pt_BR").capitalize()} salto: {salto}')

The detail is that this module returns the string with lowercase letters ("first", "second", etc), so I use capitalize to change the first letter to uppercase.

  • 1

    In the first example, instead of using the enumerate just to access ordinais by index it would not be better to already use a zip direct? Or a zip_longest if the length of ordinais is a problem?

  • @fernandosavio Yes. I updated the reply, thank you! :-)

  • 1

    I almost forgot the +1. ;)

1


A possible solution to this problem would be:

distancia =[]
salto = 0

while nome != '':
    nome = input('Insira o nome do atleta:')
    nomes.append(nome)
    if nome == '':
        break;
    for i in range(1,6):
        salto = float(input(f'Informe a distância do {i}º salto do atleta:'))
        distancia.append(salto)
        media = sum(distancia)/len(distancia)
print(f'Atleta:{nome}')
for i in distancia:
    print(i)
print('Resultado final')
print(f'Saltos: {distancia}')
print(f'Média dos saltos: {media}')
print('Primeiro salto: {}'.format(distancia[0]))
print('Segundo salto: {}'.format(distancia[1]))
print('Terceiro salto: {}'.format(distancia[2]))

Note that in my solution I am assuming that there are the 3 indexes filled in the distance list. If this assumption is not true, then an access to an invalid memory address will occur.

Iterative version

An iterative version of this approach can be used. In this case I will not write out the jump values, I will use the ordinal number indicator (º), in the enumerate function I used the value start=1, because in python the arrays are indexed from zero index, this way will be printed correctly the value for the jump:

for num, salto in enumerate(distancia, start=1):
    print("{}º salto: {}".format(num, salto))

This way we could have an unlimited amount of jumps that they would be displayed in an appropriate way.

Browser other questions tagged

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