Comment créer différents noms de variables en boucle? [dupliquer]


125

À titre d'exemple ...

for x in range(0,9):
    string'x' = "Hello"

Donc je me retrouve avec string1, string2, string3 ... tous égaux à "Bonjour"


34
La réponse est que vous ne voulez pas faire cela. Utilisez plutôt une liste.
Sven Marnach

2
Si c'est là que vous voulez l'utiliser, vous pouvez y x = ["Hello" * 9]accéder par x[0], x[1] ...Si vous voulez l'utiliser d'une manière différente, je pense que vous devrez nous donner un peu plus de fond de code.
James Khoury

3
Si jamais j'ai le pouvoir sur une langue, utiliser des nombres dans des noms de variables me donnera SyntaxError: Use a data structure.;-)
Jochen Ritzel

1
et n'oubliez pas votre string0;)
wim

10
@James Khoury: Ce n'est pas tout à fait vrai. Cela finirait par xêtre une liste contenant un seul élément - la chaîne "HelloHelloHelloHelloHelloHelloHelloHelloHello". Je pense que tu voulais dire x = ["Hello"] * 9.

Réponses:


163

Sûr que vous pouvez; ça s'appelle un dictionnaire :

d = {}
for x in range(1, 10):
    d["string{0}".format(x)] = "Hello"
>>> d["string5"]
'Hello'
>>> d
{'string1': 'Hello',
 'string2': 'Hello',
 'string3': 'Hello',
 'string4': 'Hello',
 'string5': 'Hello',
 'string6': 'Hello',
 'string7': 'Hello',
 'string8': 'Hello',
 'string9': 'Hello'}

J'ai dit cela un peu ironiquement, mais vraiment la meilleure façon d'associer une valeur à une autre valeur est un dictionnaire. C'est pour cela qu'il a été conçu!


62

C'est vraiment une mauvaise idée, mais ...

for x in range(0, 9):
    globals()['string%s' % x] = 'Hello'

puis par exemple:

print(string3)

te donnera:

Hello

Cependant, c'est une mauvaise pratique. Vous devriez plutôt utiliser des dictionnaires ou des listes, comme d'autres le proposent. À moins, bien sûr, que vous vouliez vraiment savoir comment le faire, mais que vous ne vouliez pas l'utiliser.


2
Pouvez-vous expliquer pourquoi c'est une mauvaise idée?
ajdigregorio

6
@paintedcones: Premièrement, il devrait y avoir une façon de le faire , et l'utilisation de dictionnaires simples est plus naturelle. Utiliser le dictionnaire global à la place est une mauvaise idée, car il crée également "implicitement" des variables globales ou les modifie. Étant donné que la définition et la modification des variables de cette manière nécessitent la notation du dictionnaire, il n'y a aucune raison d'utiliser à la globals()place de quelques simples dict.
Tadeck

Il y a quelques situations où vous devez créer un tas de variables, x1, x2, x3, etc. Mais dans la plupart des situations, utiliser un dictionnaire est vraiment la chose la plus appropriée à faire.
DevilApple227

20

Une façon de le faire est d'utiliser exec(). Par exemple:

for k in range(5):
    exec(f'cat_{k} = k*2')
>>> print(cat_0)
0
>>> print(cat_1)
2
>>> print(cat_2)
4
>>> print(cat_3)
6
>>> print(cat_4)
8

Ici, je profite du formatage de chaîne f pratique dans Python 3.6+


5
Souvenez-vous de execquelque chose, de la magie noire, des vulnérabilités d'attaque, des mauvaises choses, mais cela répond à la question telle que posée.
psaxton

18

Il est tout simplement inutile de créer des noms de variables variables. Pourquoi?

  • Ils ne sont pas nécessaires: vous pouvez tout stocker dans des listes, des dictionnaires, etc.
  • Ils sont difficiles à créer: vous devez utiliser execouglobals()
  • Vous ne pouvez pas les utiliser: comment écrivez-vous du code qui utilise ces variables? Vous devez utiliser à exec/globals()nouveau

Utiliser une liste est beaucoup plus simple:

# 8 strings: `Hello String 0, .. ,Hello String 8`
strings = ["Hello String %d" % x for x in range(9)]
for string in strings: # you can loop over them
    print string
print string[6] # or pick any of them

Je vous remercie!! J'avais besoin de choisir la forme parmi le dictionnaire ou la liste de dataframe. Et comme j'avais besoin de réorganiser le dataframe en fonction d'une certaine valeur sur le dataframe, je n'aurais pas pu utiliser la forme de dictionnaire. Oui tu as raison! Dans certains cas, il est vraiment inutile de créer des noms de variables!
Doo Hyun Shin

9

Ne faites pas cela, utilisez un dictionnaire

import sys
this = sys.modules[__name__] # this is now your current namespace
for x in range(0,9):
    setattr(this, 'string%s' % x, 'Hello')

print string0
print string1
print string2
print string3
print string4
print string5
print string6
print string7
print string8

ne faites pas cela, utilisez un dict

globals () présente un risque car il vous donne sur quoi pointe actuellement l'espace de noms, mais cela peut changer et modifier le retour de globals () n'est donc pas une bonne idée


8
for x in range(9):
    exec("string" + str(x) + " = 'hello'")

Cela devrait fonctionner.


3

J'utiliserais une liste:

string = []
for i in range(0, 9):
  string.append("Hello")

De cette façon, vous auriez 9 "Hello" et vous pourriez les obtenir individuellement comme ceci:

string[x]

xidentifierait quel "Bonjour" vous voulez.

Alors, print(string[1])j'imprimerais Hello.


1
Contrairement à certains langages, vous ne pouvez pas attribuer des éléments dans une liste Python qui n'existent pas encore (vous obtiendrez une erreur "index d'affectation de liste hors de portée"). Vous voudrez peut-être utiliser à la string.append("Hello")place.
Greg Hewgill

1
J'aurais dû le savoir, merci de me le rappeler. C'est réparé.
Lledargo

Votre droite, je pensais ajouter à la fin d'une chaîne, pas ajouter à un tableau. Mes excuses à tous.
Lledargo

Pédantiquement 'vous auriez 9 "Bonjour" "devrait être" vous auriez 1 "Bonjour" 9 fois'. C'est la même chaîne répétée, pas neuf chaînes de différence.
Duncan

2

Je pense que le défi ici n'est pas de faire appel à global ()

Je définirais personnellement une liste pour vos variables (dynamiques) à conserver, puis je les ajouterais dans une boucle for. Utilisez ensuite une boucle for distincte pour afficher chaque entrée ou même exécuter d'autres opérations.

Voici un exemple - j'ai un certain nombre de commutateurs de réseau (disons entre 2 et 8) dans diverses succursales. Maintenant, je dois m'assurer que j'ai un moyen de déterminer combien de commutateurs sont disponibles (ou de test en direct - ping) dans une branche donnée, puis d'effectuer certaines opérations sur eux.

Voici mon code:

import requests
import sys

def switch_name(branchNum):
    # s is an empty list to start with
    s = []
    #this FOR loop is purely for creating and storing the dynamic variable names in s
    for x in range(1,8,+1):
        s.append("BR" + str(branchNum) + "SW0" + str(x))

    #this FOR loop is used to read each of the switch in list s and perform operations on
    for i in s:
        print(i,"\n")
        # other operations can be executed here too for each switch (i) - like SSH in using paramiko and changing switch interface VLAN etc.


def main():  

    # for example's sake - hard coding the site code
    branchNum= "123"
    switch_name(branchNum)


if __name__ == '__main__':
    main()

La sortie est:

BR123SW01

BR123SW02

BR123SW03

BR123SW04

BR123SW05

BR123SW06

BR123SW07


2

L'utilisation de dictionnaires devrait être la bonne façon de conserver les variables et les valeurs associées, et vous pouvez utiliser ceci:

dict_ = {}
for i in range(9):
     dict_['string%s' % i]  = 'Hello'

Mais si vous souhaitez ajouter les variables aux variables locales, vous pouvez utiliser:

for i in range(9):
     exec('string%s = Hello' % i)

Et par exemple si vous souhaitez leur attribuer des valeurs de 0 à 8, vous pouvez utiliser:

for i in range(9):
     exec('string%s = %s' % (i,i))

0

Le dictionnaire peut contenir des valeurs et des valeurs peuvent être ajoutées à l'aide de la méthode update (). Vous voulez que votre système crée des variables, vous devez donc savoir où les conserver.

variables = {}
break_condition= True # Dont forget to add break condition to while loop if you dont want your system to go crazy.
name = variable
i = 0 
name = name + str(i) #this will be your variable name.
while True:
    value = 10 #value to assign
    variables.update(
                  {name:value})
    if break_condition == True:
        break
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.