【问题标题】:Use iterator as variable name in python loop在python循环中使用迭代器作为变量名
【发布时间】:2012-01-21 18:35:47
【问题描述】:

我一直想知道是否有一种方法可以在 Python 循环中使用迭代器作为变量名。例如,如果我想创建对象v0v1v2,有没有办法这样做:

for i in range(3):
    v + str(i) = i**2

我知道语法是错误的,但思路应该很清楚。相当于 R 中的paste 的东西?非常感谢,

【问题讨论】:

  • 这与你标题中的问题有什么关系?更好的是,您为什么要这样做?
  • 有很多方法可以做到这一点,但您最好分配给另一个列表,然后按索引访问该列表。
  • 我已更改问题名称。我遇到过以这种特定方式存储或引用数据会有所帮助的情况(我知道还有其他方式,但这有时会很有用)。
  • 给我看一个比list更好的例子。
  • 人们应该能够注意到 [accepted] 答案中的一个共同主题:stackoverflow.com/questions/1373164/…stackoverflow.com/questions/4277056/…stackoverflow.com/questions/6677424/…

标签: python loops iterator


【解决方案1】:

内置方法globals()返回一个表示当前全局符号表的字典。

您可以像这样向globals 添加一个变量:

globals()["v" + str(i)] = i**2

仅供参考:这是您问题的答案,但肯定不是推荐的方法。直接操作globals 是一种黑客解决方案,大多数情况下可以避免使用更清洁的替代方案。 (查看此线程中的其他 cmets

【讨论】:

  • +1 因为这解决了它。我不建议这样做,但它可以解决它。您也可以对任何关联数组类型执行类似操作,而不仅仅是 globals 数组,但您必须访问该数组才能提取它。
  • 我讨厌人们提供的解决方案允许人们做他们不应该做的事情。我不知道我是否应该反对这个鼓励一个坏主意,因为这正是 OP 所要求的。
  • 有些人只是简单地提供问题的答案,而另一些人则在争论寻找更好的方法来实现某事。我认为正是这两种答案类型的混合使 SO 如此珍贵。 (但我同意你的观点,不推荐使用globals
  • 嘿。好的,回答问题时 +1 :) 但是,当提出某些建议时……“通常不赞成”……像这样,通常最好在答案本身中指出它的一般问题/限制。 (我之前用过globals()locals(),但在非常特殊情况下。)
  • 我很困惑为什么有人想尝试在 python 中创建变量?对我来说,您似乎无法处理刚刚创建的变量,并且必须通过全局或本地进行挖掘才能找到它们。 OP 能否将问题更改为“为什么有人会在 py 中创建变量?”所以我可以看到答案?
【解决方案2】:

虽然这不会尝试直接回答问题(请参阅 geccos 的答案),但这通常是此类操作的“批准”方法:

v = [i**2 for i in range(3)]

print v[0] # 0
print v[1] # 1
print v[2] # 4

一般来说,使用 ADT(在本例中为列表)来表示给定问题比尝试创建“动态变量”或“变量变量”更简洁且更易于扩展。

编码愉快。


虽然上面使用了索引,但“变量变量”的更一般形式通常是用字典完成的:

names = dict(("v" + str(i), i**2) for i in range(3))
print names["v2"] # 4

而且,对于一组固定的有限(和相对较小的)变量,也可以使用“解包”:

v0, v1, v2 = [i**2 for i in range(3)]
print v1 # 1

【讨论】:

    【解决方案3】:

    我更喜欢 xrange() 而不是 range()。 这是给你的代码:

    for i in xrange(3):
        exec("v"+str(i)+" = i * i")
    

    即使... 你应该考虑使用列表

    【讨论】:

      【解决方案4】:

      有几种方法可以做到这一点,最好的方法取决于您在创建变量后实际想要对它们做什么。

      globals()locals() 可以工作,但它们不是你想要的。 exec() 也可以,但比 globals()locals() 还要糟糕。

      如果v1v2v3 是同构的并且您只想按索引访问它们,那么@user166390 提到的列表理解是一个好主意。

      >>> v = [i ** 2 for i in range(3)]
      >>> v[0]
      0
      >>> v[1]
      1
      >>> v[2]
      4
      

      如果总是恰好三个元素,你也可以这样做:

      >>> v1, v2, v3 = [i ** 2 for i in range(3)]
      >>> v1
      0
      >>> v2
      1
      >>> v3
      2
      

      如果对象更加个性化,那就太好了,因为您可以给它们自己的名字。

      另一个中间选项是使用dict

      d = {}
      for i, val in enumerate(range(3)):
          d["v{}".format(i)] = val
      
      >>> d["v0"]
      0
      >>> d["v1"]
      1
      >>> d["v2"]
      4
      

      或使用 dict 理解的上述方法的快捷方式:

      d = {"v{}".format(i): val for i, val in enumerate(range(3))}
      

      【讨论】:

        【解决方案5】:
        # Python 3.8.2 (default, Feb 26 2020, 02:56:10)
        

        使用 globals() 创建变量名并使用 exec() 解包元组:

        glo = globals()
        listB=[]
        for i in range(1,11):
            glo["v%s" % i] = i * 10
            listB.append("v%s" % i)
        
        def print1to10():
            print("Printing v1 to v10:")
            for i in range(1,11):
                print("v%s = " % i, end="")
                print(glo["v%s" % i])
        
        print1to10()
        
        listA=[]
        for i in range(1,11):
            listA.append(i)
        
        listA=tuple(listA)
        print(listA, '"Tuple to unpack"')
        
        listB = str(str(listB).strip("[]").replace("'", "") + " = listA")
        
        print(listB)
        
        exec(listB)
        
        print1to10()
        

        输出:

        Printing v1 to v10:
        v1 = 10
        v2 = 20
        v3 = 30
        v4 = 40
        v5 = 50
        v6 = 60
        v7 = 70
        v8 = 80
        v9 = 90
        v10 = 100
        (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) "Tuple to unpack"
        v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 = listA
        Printing v1 to v10:
        v1 = 1
        v2 = 2
        v3 = 3
        v4 = 4
        v5 = 5
        v6 = 6
        v7 = 7
        v8 = 8
        v9 = 9
        v10 = 10
        

        请注意,可以使用 locals()、globals() 或 vars():

        vList = []
        for i in range(3):
            vars()["v%s" % i] = i ** 2
            vList.append(vars()["v%s"%i])
        
        for i in range(3):
            print("v%s"%i, "=", vList[i])
        

        输出:

        v0 = 0
        v1 = 1
        v2 = 4
        

        此示例使用字典而不是列表:

        vDict = {}
        for i in range(3):
            vars()["v%s" % i] = i ** 2
            vDict[i] = vars()["v%s" % i]
        
        for i in range(3):
            print("v%s"%i, "=", vDict[i])
        

        输出:

        v0 = 0
        v1 = 1
        v2 = 4
        

        还要注意,无论是从字符串创建变量、分配直接值还是分配间接值,locals()、globals() 和 vars() 都可以互换使用:

        vDict = {}
        for i in range(1000):
            vars()["v%s" % i] = i ** 2
            vDict[i] = vars()["v%s" % i]
        
        for i in range(0, 1000, 200):
            print("v%s"%i, "=", vDict[i])
        
        print()
        locals()[vDict[200]] = 1999  #indirect assignment
        print("v200 =", vDict[200], "(direct v200 value is unchanged)") 
        print()
        print("v200 =", vars()[vDict[200]], "(indirect value)")
        print("v200 =", locals()[vDict[200]], "(indirect value)") 
        print("v200 =", globals()[vDict[200]], "(indirect value)")
        print()
        
        vars()["v%s"%200] = 2020
        print("v200 =", globals()["v%s"%200], "(direct value)")
        v200 = 2021
        print("v200 =", locals()["v%s"%200], "(direct value)")
        

        输出:

        v0 = 0
        v200 = 40000
        v400 = 160000
        v600 = 360000
        v800 = 640000
        
        v200 = 40000 (direct v200 value is unchanged)
        
        v200 = 1999 (indirect value)
        v200 = 1999 (indirect value)
        v200 = 1999 (indirect value)
        
        v200 = 2020 (direct value)
        v200 = 2021 (direct value)
        

        工作原理

        vDict = {}
        for i in range(0, 1000, 200):
            vars()["v%s" % i] = i ** 2
            vDict[i] = vars()["v%s" % i]
        
        for i in range(0, 1000, 200):
            print("v%s"%i, "=", vDict[i])
        
        print()
        # indirect assignment using 40000 as variable (variable variable)
        locals()[vDict[200]] = 1999  # using value 40000 as a variable
        print("v200 =", vDict[200], "(direct v200 value is unchanged)") 
        print()
        print("v200 =", vars()[vDict[200]], "(indirect value from key 40000)")
        print("{ '40000':", globals()[40000],"}")
        print()
        if vars()[vDict[200]] == globals()[40000]:
          print("They are equal!")
        if globals()[vDict[200]] == locals()[40000]:
          print("They are equal!")
        

        输出:

        v0 = 0
        v200 = 40000
        v400 = 160000
        v600 = 360000
        v800 = 640000
        
        v200 = 40000 (direct v200 value is unchanged)
        
        v200 = 1999 (indirect value from key 40000)
        { '40000': 1999 }
        
        They are equal!
        They are equal!
        

        【讨论】:

          猜你喜欢
          • 2015-04-21
          • 2015-07-28
          • 1970-01-01
          • 1970-01-01
          • 2019-01-09
          • 2014-11-09
          • 2016-10-06
          • 2014-03-24
          • 1970-01-01
          相关资源
          最近更新 更多