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ść”


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!


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ć.


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+


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

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



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.


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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.