【问题标题】:In Python, how to create a large number of variables in a loop? [duplicate]在Python中,如何在一个循环中创建大量变量? [复制]
【发布时间】:2011-11-14 22:35:16
【问题描述】:

我正在寻找一种在 python 3.2 中创建大量变量并为它们赋值的方法。类似的东西

X = 10
Y = 10
A = 0
B = 0
while X >= 0:
    while Y >= 0:
        cell[C]X[A] = A
        cell[C]Y[B] = B
        B = B + 1
        Y = Y - 1
        C = C + 1
    A = A + 1
    X = X - 1

这将最佳地创建 cell1X1、cell1Y1、cell2X1、cell2Y2 等 200 个变量。

这可能吗?怎么做?

请记住,我对 python 还是很陌生,所以请让事情尽可能简单。

另外,虽然我知道还有其他方法可以做到这一点,而且它们可能更好,但我仍然想知道如何以这种方式做事。

我知道字典可能在各方面都更好,但这不是我想要的。

感谢您的帮助。

编辑:当我说 Python 新手时,我的意思是说一般的编程新手。像很新。比如,最近刚刚学会了如何编写函数。

【问题讨论】:

  • 字典确实比你最终可能遇到的任何能够以你所想的方式实现这一目标的怪物更复杂。
  • 由于您提出的问题可以用“不要那样做”来合理回答,如果您更全面地解释为什么要这样做,您可能会得到更好的答案想要这样做。使用现有的(脑死亡)代码?学习的乐趣?受虐狂?
  • #1 是一个蹩脚的理由。它们非常简单,您基本上已经将本地范围视为字典(不是!)。 #2 是一个光荣的目标,但主要的反对意见,至少对我来说,是风格和自律问题,你可能不同意(目前)并且可能无法在你的小程序中充分展示它们现在写下来。当然,您可以尝试使用它,但在将它引入任何项目之前我会三思而后行,而且我尤其是不会推迟适应它的适当替代方案。
  • 从好的方面来说,如果您设法在不使用字典的情况下完成这项工作,那么学习字典将是一种乐趣。
  • 你还没有说在你创建了这 200 个变量之后你要做什么......

标签: python variables loops python-3.x


【解决方案1】:

老实说,这个问题的唯一合理答案是:不要那样做,而是学习如何使用字典。

我相信这也是最有帮助的答案。您已经在问题中声明 (1) 您是 Python 新手,(2) 您是一般编程新手,以及 (3) 您接受字典可能在各个方面都更好你在问什么。

您说您是在“出于学习目的”询问。好吧,更有效的方法是先多学习一点语言,然后再坚持做一些你承认不受语言本身鼓励的事情,当然也不会受到任何提供他们的 cmets 和答案的人的鼓励。

在这种情况下,了解字典的工作原理。我想你不会觉得它们那么复杂。即使你这样做了,无论如何,真正理解它们也值得你花时间和精力,因为字典是 Python 的一个非常基本的特性。它们在 Python 中随处可见,即使您不坚持使用 Python,许多其他语言也大量使用相同的概念(尽管经常使用不同的名称,例如“关联数组”、“哈希”、“表”,或者其他东西)。

在您对字典本身感到满意之后,如果您仍然无法弄清楚如何将它们应用于某些特定的编程问题,那么也许是时候问另一个问题了。

【讨论】:

    【解决方案2】:

    就像其他人说的那样:不要那样做。不幸的是,您的程序无法让变量的名称 本身依赖于变量(实际上,有一些方法可以做到这一点,但它很复杂,而且很少是正确的方法)。

    指出你不应该这样做的原因可能很重要,不仅仅是因为它在 Python 中很复杂,而且想要这样做表明对大多数语言中代码之间的区别存在根本性的误解(包括语言中事物的名称)和data(事物的可变值)。

    在这种情况下,您实际需要的是字典、列表或类似的东西:

    至少在你的例子中,你只有两种东西,你称之为cell[C]X[A]cell[C]Y[B]。你可以把它们变成cellX[A,B]cellY[A,B],它们在python中是完全合法的结构。

    所以在循环之前,执行此操作,初始化一个空字典。

    cellX = {}
    cellY = {}
    

    然后,在循环内,你可以拥有

     cellX[C,A]=A
     cellY[C,B]=B
    

    还请注意,您的循环,就像现在一样,不是很“pythonic”。你应该考虑像for X in range(10,-1,-1):一样循环

    【讨论】:

      【解决方案3】:

      它又黑又黑,但你可以试试:

       for i in range(100):
           locals()['A%i'%i] = i
      

      但是请不要这样做。这通常是一种糟糕的做法。

      正如@delnan 指出的那样,它可能不适用于某些 python 版本和实现。 locals() 是本地命名空间,它是 Python 实现的一部分。你真的不想玩它。

      您不想这样做的另一个更重要的原因 - 这是安全性和可靠性的噩梦。您看不到所有变量名称是什么,因此您可能会不小心覆盖其他变量之一。您从同一个地方获取所有这些“变量”,因此将它们全部放在字典中是合乎逻辑的。

      我将解释它为什么起作用,至少在某些情况下:本地命名空间通常以字典的形式实现,locals() 有时会返回本地命名空间字典,而不是副本。

      这完全没有意义吗?

      Python 变量就像字典中的项目。模块有一个命名空间,函数一个命名空间,一个“全局”命名空间,等等。 locals() 为您提供最本地的命名空间,globals() 为您提供全局命名空间。

      如果本地命名空间实际上是作为字典实现的,您可以通过编辑 locals() 来编辑它(深入到 python 解释器的内部)。但是,有时本地命名空间没有实现为字典(出于性能原因) - 这发生在函数内部。在这种情况下,locals() 将为您提供命名空间的副本,您将无法对其进行编辑(或者至少,它不会更改本地命名空间)。

      还在困惑吗?不要这样做。

      【讨论】:

      • 如果这适用于所有情况和版本,我会感到惊讶,尽管我不能随便引用细节。
      • @Luingar - 字符串模板。您可以将其更改为 'A'+str(i)。
      • 赞成“请不要这样做。这通常是一种糟糕的做法。”部分:)
      • 有趣的是,这是使用字典。哇!
      • 内部函数保证可以工作。
      【解决方案4】:

      全局范围不是你想在其中创建变量的东西,我可以为你提供几种创建数组的方法:

      您可以采取多种方式。 一种是像这样相乘:

      a = [1]*5
      

      这实际上会为您构建一个 references 列表到同一个数组,这不是我们需要的 - 很好地抓住 @Aaron Dufour

      b = [[0]*5]*5
      

      但这里有一种方法可以避免创建references

      list(map(lambda x: [x]*6,[1]*5))
      

      等等。 另一种方式可能是 range 在 python 3 中它会返回自身,因此您可以将其转换为数组,如下所示:

      list(range(0,10))
      

      另一种方法可能是编写一个实际的循环, 如果您需要受循环或其他东西影响的特殊值,您可以在数组的 map 调用中编写 lambda 函数。

      这本书是 Python 的一个良好开端:Dive into Python 3

      祝你好运!

      编辑:用变量污染你的全局范围是一种不好的做法——不管是什么语言,尽量避免它。

      【讨论】:

      • 啊啊啊!不要这样做! [0]*5 没问题。 [[0]*5]*5 不是。您将有一个包含 5 个对同一列表的引用的列表。例如,如果你如图分配b,然后说b[0][0] = 1,你会发现b[1][0]b[2][0]等也等于1
      • 重新编辑:即使污染最小的本地范围也是一种不好的做法。
      • @AaronDufour 哎呀——你完全正确!没想到。
      • 感谢您提供图书链接。严重地。 :D
      猜你喜欢
      • 2012-09-08
      • 2018-05-04
      • 1970-01-01
      • 2014-04-14
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多