2 votes

Comment travailler avec le nom d'un dictionnaire imbriqué ?

J'écris un programme utilisant des dictionnaires imbriqués dans une liste. Je veux imprimer le nom de chaque dictionnaire en parcourant la liste, mais je ne sais pas comment le faire sans appeler le contenu entier du dictionnaire. Voici mon code :

sam = {
'food' : 'tortas',
'country' : 'mexico',
'song' : 'Dream On',
}
dave = {
    'food' : 'spaghetti',
    'country' : 'USA',
    'song' : 'Sweet Home Alabama',
    }

people = [sam, dave]

for person in people:
    for key, value in sorted(person.items()):
        print( #person's name +
                "'s favorite " + key + " is " + value + ".")

Voici le résultat :

's favorite country is mexico.

's favorite food is tortas.

's favorite song is Dream On.

's favorite country is USA.

's favorite food is spaghetti.

's favorite song is Sweet Home Alabama.

Tout fonctionne, j'ai juste besoin que les noms de mes dictionnaires s'impriment. Quelle est la solution ?

3voto

Selcuk Points 15733

La façon (plus) correcte de procéder consiste à construire un fichier de type dict de dict à la place, comme :

people = {'sam': {'food' : 'tortas',
                  'country' : 'mexico',
                  'song' : 'Dream On',
                  },
          'dave': {'food' : 'spaghetti',
                   'country' : 'USA',
                   'song' : 'Sweet Home Alabama',
                   }
           }

Dans ce cas, vous pouvez simplement procéder comme suit :

for name, person in people.items():
    for key, value in sorted(person.items()):
        print(name + "'s favorite " + key + " is " + value + ".")

Le texte suivant sera imprimé :

dave's favorite country is USA.
dave's favorite food is spaghetti.
dave's favorite song is Sweet Home Alabama.
sam's favorite country is mexico.
sam's favorite food is tortas.
sam's favorite song is Dream On.

À titre d'information, il est plus facile à lire d'utiliser le formatage des chaînes de caractères dans les documents suivants print déclaration :

print("{0}'s favorite {1} is {2}".format(name, key, value))

2voto

Ce que vous essayez de faire, c'est d'imprimer le nom d'une variable. Bien sûr, ce n'est pas recommandé. Si vous voulez vraiment le faire, vous devriez jeter un coup d'œil à cet article : Comment imprimer un nom de variable en python ?

Ce que je ferais, c'est de stocker le nom du dictionnaire à l'intérieur des listes. Vous pouvez le faire en changeant 'people = [sam, dave]' en 'people = [["sam", sam], ["dave", dave]]'. De cette façon, person[0] est le nom de la personne, et person[1] contient les informations.

2voto

Sean Gugler Points 646

La méthode la plus simple consiste à stocker le nom sous la forme d'une chaîne qui correspond à l'identifiant de la variable correspondante :

people = {'sam':sam, 'dave':dave}

for name, person in people.items():
    for key, value in sorted(person.items()):
        print(name + "'s favorite " + key + " is " + value + ".")

Si vous n'aimez vraiment pas l'idée de taper chaque nom deux fois, vous pouvez "mettre en ligne" les dictionnaires :

people = {
    'sam':{
        'food' : 'tortas',
        'country' : 'mexico',
        'song' : 'Dream On',
    },
    'dave':{
       'food' : 'spaghetti',
       'country' : 'USA',
       'song' : 'Sweet Home Alabama',
    }
}

Enfin, si vous pouvez compter sur le fait que ces variables se trouvent dans l'espace de noms global et que vous êtes plus préoccupé par le fait que cela fonctionne que par la pureté de la pratique, vous pouvez les trouver de cette façon :

people = ['sam', 'dave']

for name in people:
    person = globals()[name]
    for key, value in sorted(person.items()):
        print(name + "'s favorite " + key + " is " + value + ".")

1voto

Kevin J. Chase Points 2988

Les valeurs dans une liste ne sont pas vraiment variables plus. Ils ne sont pas désignés par un nom dans un espace de noms, mais par un nombre entier indiquant leur décalage par rapport au début de la liste ( 0 , 1 , ...).

Si vous voulez associer chaque dict de données avec un certain nom, vous devez le faire explicitement. Il existe deux options générales, en fonction de ce qui est responsable du suivi du nom : la collection de personnes, ou chaque personne de la collection.

Le premier et le plus facile est le collections.OrderedDict --- contrairement à la normale dict il conservera l'ordre des personnes dans votre liste.

from collections import OrderedDict

sam = {
  'food': 'tortas',
  'country': 'Mexico',
  'song': 'Dream On',
  }
dave = {
  'food': 'spaghetti',
  'country': 'USA',
  'song': 'Sweet Home Alabama',
  }
# The OrderedDict stores each person's name.
people = OrderedDict([('Sam', sam), ('Dave', dave)])

for name, data in people.items():
    # Name is a key in the OrderedDict.
    print('Name: ' + name)
    for key, value in sorted(data.items()):
        print('  {0}: {1}'.format(key.title(), value))

Alternativement, vous pouvez stocker le nom de chaque personne dans son propre fichier dict ... en supposant que vous êtes autorisé à modifier le contenu de ces dictionnaires. (De même, vous ne voudriez pas ajouter quoi que ce soit au dictionnaire de données qui vous obligerait à modifier/mettre à jour les données plus souvent que vous ne le faites déjà. Étant donné que la plupart des gens changent leur plat ou leur chanson préférés beaucoup plus souvent qu'ils ne changent de nom, cela est probablement sans danger).

sam = {
# Each dict has a new key: 'name'.
  'name': 'Sam',
  'food': 'tortas',
  'country': 'Mexico',
  'song': 'Dream On',
  }
dave = {
  'name': 'Dave',
  'food': 'spaghetti',
  'country': 'USA',
  'song': 'Sweet Home Alabama',
  }
people = [sam, dave]

for data in people:
    # Name is a value in the dict.
    print('Name: ' + data['name'])
    for key, value in sorted(data.items()):
        # Have to avoid printing the name again.
        if 'name' != key:
            print('  {0}: {1}'.format(key.title(), value))

Notez que la façon dont vous imprimez les données dépend du fait que vous stockez le nom dans la collection ( OrderedDict variante), ou dans les dict ( list variante).

0voto

Porter Robinson Points 20

Merci pour votre contribution. Ce programme est destiné à un exemple pratique dans "Python Crash Course" d'Eric Matthes, donc le format inefficace "dictionnaires dans une liste" est intentionnel. Cela dit, j'ai beaucoup appris de vos commentaires et j'ai modifié mon code pour obtenir le résultat souhaité :

sam = {
    #Added a 'name' key-value pair.
    'name' : 'sam',
    'food' : 'tortas',
    'country' : 'mexico',
    'song' : 'Dream On',
    }
dave = {
    'name' : 'dave',
    'food' : 'spaghetti',
    'country' : 'USA',
    'song' : 'Sweet Home Alabama',
    }

people = [sam, dave]

for person in people:
    for key, value in sorted(person.items()):
        #Added if statement to prevent printing the name.
        if key != 'name':
            print(person['name'].title() + "'s favorite " + key + " is " + value + ".")
    #Added a blank line at the end of each for loop.
    print('\n')

Voici le résultat :

Sam's favorite country is mexico.
Sam's favorite food is tortas.
Sam's favorite song is Dream On.

Dave's favorite country is USA.
Dave's favorite food is spaghetti.
Dave's favorite song is Sweet Home Alabama.

Merci encore à tous ceux qui ont fourni des réponses perspicaces.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X