Another alternative to not repeat this "function" three times?

Asked

Viewed 162 times

7

Make a program that reads three vectors with 10 elements each. Generate a fourth vector of 30 elements, whose values should be composed of the interspersed elements of the three other vectors. (Using Lists)

I did, but I’d like to know some way to avoid having to repeat the command for three times just like I did in the code below:

n1 = list()
n2 = list()
n3 = list()
n4 = list()

for a in range(1, 11):
    n1.append(int(input(f'Digite o {a}° elemento da 1° lista: ')))
print('='*40)

for b in range(1, 11):
    n2.append(int(input(f'Digite o {b}° elemento da 2° lista: ')))
print('='*40)

for c in range(1, 11):
    n3.append(int(input(f'Digite o {c}° elemento da 3° lista: ')))
print('='*40)

for d in range(0, 10):
    n4.append(n1[d])
    n4.append(n2[d])
    n4.append(n3[d])

print(f'Intercalando as listas 1, 2 e 3 temos:\n'
      f'{n4}')

3 answers

8

Yes, it is possible and there must be countless ways to do this.

One of them is very simple, is to create a function that contains the logic where you request the numbers from the user and add in the list.


We create the function, listAppend, that will receive the list to add the numbers that the user inform and also receives a number relative to which is the list, this is only to print 1st list, 2nd list etc:

def listAppend(vector, number):
  for a in range(1, 11):
      vector.append(int(input(f'Digite o {a}° elemento da {number}° lista: ')))
  print('='*40)

See that it is practically the same code you wrote three times, but now isolated in a function.

Now that we have this function, we can just call it to each list:

listAppend(n1, 1)
listAppend(n2, 2)
listAppend(n3, 3)

Your code would then look like this:

def listAppend(vector, number):
  for a in range(1, 11):
      vector.append(int(input(f'Digite o {a}° elemento da {number}° lista: ')))
  print('='*40)

n1 = list()
n2 = list()
n3 = list()
n4 = list()

listAppend(n1, 1)
listAppend(n2, 2)
listAppend(n3, 3)

for d in range(0, 10):
    n4.append(n1[d])
    n4.append(n2[d])
    n4.append(n3[d])

print(f'Intercalando as listas 1, 2 e 3 temos:\n'
      f'{n4}')

See online: https://repl.it/repls/LowestWorthwhileEditor

6


Whenever you want to generalize a processing that seems repeated you should take this model and parameterize the variable parts. And of course when I’m talking about parameterizing the function should have parameters. In case the list changes in each of the three and also changes the number of the list that should be printed, then it is these two parameters that should create.

def pegaDados(lista, ordinal):
    for n in range(1, 11):
        lista.append(int(input(f'Digite o {n}° elemento da {ordinal}° lista: ')))
    print('=' * 40)

n1 = list()
n2 = list()
n3 = list()
n4 = list()
pegaDados(n1, 1)
pegaDados(n2, 2)
pegaDados(n3, 3)

for n in range(0, 10):
    n4.append(n1[n])
    n4.append(n2[n])
    n4.append(n3[n])

print(f'Intercalando as listas 1, 2 e 3 temos:\n'
      f'{n4}')

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

You can improve some things like catching an exception if something is typed wrong, which is easier to do since now only has a code to do.

And you can even make a loop to call to generalize to the call of functions. But for this to work you will have to create a list of lists, so you pass each of the lists through an index of the main list. If you think you can do this already, it might be a good next exercise.

1

I would use a list of lists instead of variables n1, n2, etc (such as probably is an exercise, and exercises tend to have artificial limitations like "cannot use [useful native resource that makes it easier to solve the problem]", I understand that you may not want to use this, but anyway I leave registered here the alternative).

def ler_dados_lista(indice_lista, tamanho):
    lista = []
    for n in range(tamanho):
        lista.append(int(input(f'Digite o {n + 1}° elemento da {indice_lista + 1}ª lista: ')))
    print('=' * 40)
    return lista

listas = []
for i in range(3):
    listas.append(ler_dados_lista(i, 10))

intercalados = []
for elementos in zip(*listas):
    intercalados.extend(elementos)

print(f'Intercalando as listas 1, 2 e 3 temos:\n{intercalados}')

The function that reads the data from a list returns this list, and so I can add it to the list of lists using a for simple. At the end, the variable listas will be a list containing the 3 lists that have been read.

Then to create the list with the interleaved elements, I use zip, that serves to go through several lists at once (just what you want to do).

The asterisk before listas serves to make the unpacking, that is to say, zip(*listas) is the same as zip(listas[0], listas[1], listas[2]), with the difference being more succinct and mainly working without I need to know the amount of lists.

At each iteration, the variable elementos will be a tuple containing the elements of each of the lists. In the first iteration, it will have the first element of each list, in the second iteration, the second element and so on.

At last, I use extend to add all elements at once (instead of calling append several times).

Also note that you can create an empty list using [].


To make it more succinct and pythonic, you can exchange the loops above by list comprehensions:

def ler_dados_lista(indice_lista, tamanho):
    lista = [ int(input(f'Digite o {n + 1}° elemento da {indice_lista + 1}ª lista: ')) for n in range(tamanho) ]
    print('=' * 40)
    return lista

listas = [ ler_dados_lista(i, 10) for i in range(3) ]

from itertools import chain
intercalados = list(chain.from_iterable(elementos for elementos in zip(*listas)))
print(f'Intercalando as listas 1, 2 e 3 temos:\n{intercalados}')

You could also do so (the difference is it won’t print a lot of "=" between messages - if this is desired, then keep the function ler_dados_lista):

listas = [
  [ int(input(f'Digite o {n + 1}° elemento da {i + 1}ª lista: ')) for n in range(10) ]
  for i in range(3)
]

Browser other questions tagged

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