Jak tworzyć różne nazwy zmiennych w pętli? [duplikować]

125

Na przykład do celów ...

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

W rezultacie otrzymuję ciąg1, ciąg2, ciąg3 ... wszystkie równe „Cześć”

Takkun
źródło
34
Odpowiedź brzmi: nie chcesz tego robić. Zamiast tego użyj listy.
Sven Marnach
2
Jeśli chcesz go użyć w tym miejscu, możesz uzyskać x = ["Hello" * 9]do niego dostęp, x[0], x[1] ...jeśli chcesz użyć go w inny sposób, myślę, że będziesz musiał podać nam więcej tła kodu.
James Khoury
3
Jeśli kiedykolwiek będę miał władzę nad językiem, to użycie liczb w nazwach zmiennych da SyntaxError: Use a data structure.;-)
Jochen Ritzel
1
i nie zapomnij swojego string0;)
wim
10
@James Khoury: To nie do końca w porządku. To by skończyć z xbycia lista zawierająca pojedynczy element - ciąg „HelloHelloHelloHelloHelloHelloHelloHelloHello”. Myślę, że miałeś na myśli x = ["Hello"] * 9.

Odpowiedzi:

162

Oczywiście że możesz; nazywa się to słownikiem :

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'}

Powiedziałem to nieco z przymrużeniem oka, ale tak naprawdę najlepszym sposobem na powiązanie jednej wartości z inną jest słownik. Do tego został zaprojektowany!

Wilk
źródło
62

To naprawdę zły pomysł, ale ...

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

a potem na przykład:

print(string3)

da tobie:

Hello

Jednak jest to zła praktyka. Zamiast tego powinieneś używać słowników lub list, tak jak proponują inni. Chyba że, oczywiście, naprawdę chciałeś wiedzieć, jak to zrobić, ale nie chciałeś tego używać.

Tadeck
źródło
2
Czy możesz wyjaśnić, dlaczego to zły pomysł?
ajdigregorio
6
@paintedcones: Po pierwsze, powinien być na to jeden sposób , a używanie prostych słowników jest bardziej naturalne. Używanie zamiast tego słownika globalnego jest złym pomysłem, ponieważ także „niejawnie” tworzy zmienne globalne lub je modyfikuje. Ponieważ zarówno ustawianie, jak i modyfikowanie zmiennych w ten sposób wymaga notacji słownikowej, nie ma powodu, aby używać globals()zamiast prostego dict.
Tadeck,
Jest kilka sytuacji, w których musisz utworzyć kilka zmiennych, x1, x2, x3 itd. Jednak w większości sytuacji używanie słownika jest naprawdę najwłaściwszą rzeczą do zrobienia.
DevilApple 227
20

Możesz to zrobić między innymi za pomocą exec(). Na przykład:

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

Tutaj korzystam z wygodnego formatowania napisów f w Pythonie 3.6+

Collin W.
źródło
5
Pamiętaj o execczymś, czarnej magii, podatnościach na ataki, złych rzeczach, ale to odpowiada na zadane pytanie.
psaxton
18

Tworzenie nazw zmiennych jest po prostu bezcelowe. Czemu?

  • Są niepotrzebne: możesz przechowywać wszystko na listach, słownikach i tak dalej
  • Trudno je stworzyć: musisz użyć execlubglobals()
  • Nie możesz ich używać: jak piszesz kod, który używa tych zmiennych? Musisz użyć exec/globals()ponownie

Korzystanie z listy jest znacznie łatwiejsze:

# 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
Jochen Ritzel
źródło
Dziękuję Ci!! Musiałem wybrać formularz spośród słownika lub listy dataframe. A ponieważ musiałem zmienić kolejność ramki danych na podstawie określonej wartości w ramce danych, nie mogłem użyć formularza słownikowego. Tak, masz rację! W niektórych przypadkach tworzenie nazw zmiennych jest naprawdę bezcelowe!
Doo Hyun Shin
9

Nie rób tego, używając słownika

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

nie rób tego, użyj dyktu

globals () wiąże się z ryzykiem, ponieważ daje to, na co aktualnie wskazuje przestrzeń nazw, ale może się to zmienić, dlatego modyfikowanie wyniku z globals () nie jest dobrym pomysłem

Aaron Goldman
źródło
8
for x in range(9):
    exec("string" + str(x) + " = 'hello'")

To powinno działać.

Abhishek Rai
źródło
3

Użyłbym listy:

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

W ten sposób miałbyś 9 "Hello" i możesz je otrzymać indywidualnie w ten sposób:

string[x]

Gdzie xmożna zidentyfikować, które „Hello” chcesz.

Więc print(string[1])wydrukowałby Hello.

Lledargo
źródło
1
W przeciwieństwie do niektórych języków, nie możesz przypisać do elementów na liście Pythona, które jeszcze nie istnieją (otrzymasz błąd „indeks przypisania listy poza zakresem”). Możesz string.append("Hello")zamiast tego użyć .
Greg Hewgill
1
Powinienem był to wiedzieć, dziękuję za przypomnienie. Jest naprawione.
Lledargo
Masz rację, myślałem o dodaniu do końca łańcucha, a nie o dodaniu do tablicy. Przepraszam wszystkich.
Lledargo
Pedantycznie „miałbyś 9 razy„ Hello ””, powinno być „miałbyś 1„ Hello ”9 razy”. To ten sam ciąg powtórzony, a nie dziewięć ciągów różnicowych.
Duncan
2

Myślę, że tutaj wyzwaniem nie jest odwoływanie się do funkcji global ()

Osobiście zdefiniowałbym listę twoich (dynamicznych) zmiennych, które mają być przechowywane, a następnie dołączam do niej w pętli for. Następnie użyj oddzielnej pętli for, aby wyświetlić każdy wpis, a nawet wykonać inne operacje.

Oto przykład - mam kilka przełączników sieciowych (powiedzmy od 2 do 8) w różnych BRanches. Teraz muszę się upewnić, że mam sposób na określenie, ile przełączników jest dostępnych (lub aktywnych - test ping) w danej gałęzi, a następnie wykonać na nich pewne operacje.

Oto mój kod:

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()

Wynik to:

BR123SW01

BR123SW02

BR123SW03

BR123SW04

BR123SW05

BR123SW06

BR123SW07

Cumar Chan
źródło
2

Używanie słowników powinno być właściwym sposobem na zachowanie zmiennych i powiązanych z nimi wartości. Możesz użyć tego:

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

Ale jeśli chcesz dodać zmienne do zmiennych lokalnych, możesz użyć:

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

Na przykład, jeśli chcesz przypisać im wartości od 0 do 8, możesz użyć:

for i in range(9):
     exec('string%s = %s' % (i,i))
Ashkan Mirzaee
źródło
0

Słownik może zawierać wartości, a wartości można dodawać za pomocą metody update (). Chcesz, aby system tworzył zmienne, więc powinieneś wiedzieć, gdzie się zachować.

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
Ogibalboa
źródło