Bring only the values of the Python keys

Asked

Viewed 333 times

2

I need to bring one dict only the values of chave['nota'], but it only brings once.

Follow the code:

def AlunoeNota(disciplinas, nome):
print('Aluno da FHO '+nome + '- SI' )
for nota in disciplinas.get('nota'):
    print(nota)

dicfinal = {}
disciplina1 = {'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': '10'}
disciplina1.update({'nome2': 'Redes', 'sigla2': 'CH4T0', 'periodo2': 'Noturno', 'nota2': '8'})
dicfinal.update(disciplina1)

AlunoeNota(dicfinal,'Duener')

As you can see, I have two dict that I made the junction, but it always brings the value 10 and I need the note 8 also, as I would do in this case?

  • 1

    I had to change the keys because if not, the update that is the merge would not replace the current one. Is there any other way?

4 answers

2

As your keys in the dictionary are different, do the get putting only one of the names, will not work.

If you repair well, in fact your code is looping in the return of the note key, thus printing the 10 string in two lines:

for nota in disciplinas.get('nota'):
  print(nota)

Unfortunately it is far from what you wish.


There are numerous ways you can implement this, one of them is to print out all the keys that start with the word note, to know the keys of a dictionary, you can use the method keys:

disciplinas.keys()

Having the keys in hand, you check if the key starts with the word note, for this, use the method startswith:

chave.startswith("nota")

Now putting it all together, you would have the following code within the function AlunoeNota:

  for key in disciplinas.keys():
    if key.startswith("nota"):
      print(disciplinas[key])

This whole instruction can be in just one line:

[print(disciplinas[key]) for key in disciplinas.keys() if key.startswith("nota")]

Another way is to change the function AlunoeNota to receive a list of keys that will be printed:

def AlunoeNota(disciplinas, nome, chaves):
  print('Aluno da FHO ' + nome + ' - SI' )

  for chave in chaves:
      print(disciplinas[chave])

Then when you call the function, you send the third parameter telling which keys you want to print:

AlunoeNota(dicfinal,'Duener', ["nota","nota2"])

As a last suggestion, you can create a list of dictionaries, with this, you will only have a note key, which personally I think is much better.

I would have both dictionaries:

python = {'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': '10'}
redes = {'nome': 'Redes', 'sigla': 'CH4T0', 'periodo': 'Noturno', 'nota': '8'}

Put them both on a list:

notasAluno = [python, redes]

Send the list to the function AlunoeNota:

AlunoeNota(notasAluno,'Duener')

And the function, would loop in the list, always printing the note key:

def AlunoeNota(disciplinas, nome):
  print('Aluno da FHO ' + nome + ' - SI' )

  for dado in disciplinas:
      print(dado["nota"])

With this, you can access the dictionary data in a much better way, and even format the output, for example:

print(f'A matéria {dado["nome"]} teve a nota {dado["nota"]}')
  • Incredible, you gave me several ways to solve my problem, I really liked the last one for being simpler. Thank you Daniel.

2


Try this:

def AlunoeNota(lista, nome):
    print('Aluno da FHO ' + nome + '- SI' )
    for disciplina in lista:
        print(disciplina['nota'])

disciplina1 = {'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': 10}
disciplina2 = {'nome': 'Redes', 'sigla': 'CH4T0', 'periodo': 'Noturno', 'nota': 8}
lista = [disciplina1, disciplina2]

AlunoeNota(lista, 'Duener')

Basically, each dictionary should be 1 and only 1 discipline record.

Trying to put two records in the same dictionary, will create a hideous gambiarra and that is not the way, it should represent only one thing and not two.

To have multiple records of subjects, you create a list of dictionaries.

And finally, the note is a number, not a string.

  • Thank you very much guy, it worked out like I wanted.

0

In a very concise way,

that would be it:

dicfinal = {}
disciplina1 = {'Primeiro' : {'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': '10'}}
disciplina1.update({'Segundo' : {'nome': 'Redes', 'sigla': 'CH4T0', 'periodo': 'Noturno', 'nota': '8'}})
dicfinal.update(disciplina1)



cont = 0
for item in (dicfinal):
    print(item)
    lista = list(dicfinal.values())
    print('Aluno da FHO '+lista[cont]['nome'] + '- SI' )
    print('Nota: '+lista[cont]['nota'])
    cont += 1

It turns out I just changed the structure of the ICT a little bit, and I’m picking it up by the index.

Upshot:

First Student at FHO Python-SI Note: 10

According to FHO Redes- SI student Note: 8

  • It worked too, thank you.

0

Based on your comment:

I had to change the keys because if not, the update that is the merge would not replace the current one. Is there any other way?

Yes, and the other answers indicated a way, which is to create a list of dictionaries. But there’s still a catch: how do you associate these notes with a student? 'Cause your code allows you to do that:

AlunoeNota(lista, 'Duener')
AlunoeNota(lista, 'Fulano')
AlunoeNota(lista, 'Ciclano')

And the same grades will be printed as if they were 3 different students. There is no relationship between the grades and the student’s name: the function AlunoeNota accepts any list of notes and any name, and assumes that the notes are from that person.


To relate the list of notes to a particular student, one way is to create a dictionary with the following structure:

nome_aluno_1: [ lista de notas ],
nome_aluno_2: [ lista de notas ],
etc

That is, the key of the dictionary is the name of the student, and its value is the respective list of notes of the same (and this list contains several other dictionaries, each representing a discipline). Then it would look like this:

alunos_notas = {
    'Fulano': [ # notas do Fulano em cada disciplina
      { 'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': 10 },
      { 'nome': 'Redes', 'sigla': 'CH4T0', 'periodo': 'Noturno', 'nota': 8 }
    ],
    'Ciclano': [ # notas do Ciclano em cada disciplina
      { 'nome': 'Python', 'sigla': 'F0D4', 'periodo': 'Noturno', 'nota': 5 },
      { 'nome': 'Redes', 'sigla': 'CH4T0', 'periodo': 'Noturno', 'nota': 2 }
    ]
}

def AlunoeNota(alunos_notas, aluno):
    if aluno in alunos_notas:
        print(f'Notas do {aluno}:')
        for disciplina in alunos_notas[aluno]:
            print(f'- {disciplina["nome"]}: {disciplina["nota"]}')
    else:
        print(f'Notas do aluno {aluno} não encontradas')

AlunoeNota(alunos_notas, 'Fulano')
AlunoeNota(alunos_notas, 'Beltrano')

Now I validate if the student’s grades exist in the dictionary, and only print if they exist. The output is:

Notas do Fulano:
- Python: 10
- Redes: 8
Notas do aluno Beltrano não encontradas

You can also, if you want, create a function that prints the grades of all students:

def mostrar_notas(alunos_notas):
    for aluno, disciplinas in alunos_notas.items():
        print(f'Notas do {aluno}:')
        for disciplina in disciplinas:
            print(f'- {disciplina["nome"]}: {disciplina["nota"]}')

mostrar_notas(alunos_notas)

Exit:

Notas do Fulano:
- Python: 10
- Redes: 8
Notas do Ciclano:
- Python: 5
- Redes: 2

Or, to reuse the first existing function:

def mostrar_notas(alunos_notas):
    for aluno in alunos_notas.keys():
        AlunoeNota(alunos_notas, aluno)

Of course, the above structure is still a little redundant, because it repeats data from the disciplines (in real systems this would be separate, but there is too much of the scope of the question).

Browser other questions tagged

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