【问题标题】:Filling a list in Python在 Python 中填充列表
【发布时间】:2017-01-06 02:19:44
【问题描述】:

我是 Python 新手。我正在尝试用文件夹中一堆图像的文件名填充列表。它们都以“frameinstance”开头,然后是一个 0-40 的数字,即“frameinstance0.png”。我尝试了下面的代码,但我收到了 MemoryError 错误。

filenamelist = []
i = 0
for i in range(0,40):
  filenamelist = [str(filenamelist) + "frameinstance" + str(i)]

我也试过这个。我的输出很接近,但它不是一个列表。

filenamelist = []
i = 0

for i in range(0,40):
  filenamelist = str(filenamelist) + "frameinstance" + str(i)

print(filenamelist)

输出为:[]frameinstance0frameinstance1frameinstance2frameinstance3frameinstance4frameinstance5frameinstance6frameinstance7frameinstance8frameinstance9frameinstance10frameinstance11frameinstance12frameinstance13frameinstance14frameinstance15frameinstance16frameinstance17frameinstance18frameinstance19frameinstance20frameinstance21frameinstance22frameinstance23frameinstance24frameinstance25frameinstance26frameinstance27frameinstance28frameinstance29frameinstance30frameinstance31frameinstance32frameinstance33frameinstance34frameinstance35frameinstance36frameinstance37frameinstance38frameinstance39

【问题讨论】:

    标签: python list python-3.x for-loop


    【解决方案1】:

    具有基本的列表理解:

    filenamelist = ["frameinstance{}".format(i) for i in range(41)]
    

    在第一个代码中,您总是更改filenamelist 的值,方法是将其转换为越来越长的字符串,最终以MemoryError 结尾。查看Ryan's answer 了解更多信息,特别是为什么它不会在第二个代码中发生。

    在第二个代码中,您将[] 放入filenamelist,然后将其与"frameinstance" + str(i) 连接,因此在每次迭代时,您在此字符串的末尾连接"frameinstancei"。 您最终会得到一个以"[]" 开头的字符串,然后是"frameinstancei" 40 次。


    不过有几件事:

    • 当你建立一个列表时,或者使用上面的列表推导来处理短列表,或者使用append 方法。通常,写 filenamelist.append("frameinstance{}".format(i)) 而不是 filenamelist = ...
    • 不推荐使用"blah" + str(x) + "blah" 来打印字符串。相反,请使用format 方法:"blah{}blah".format(x)
    • 不要忘记range(n) 提供了从0n-1 的整数。因此,您的呼叫应该是range(0,41) 而不是range(0,40),并且可能只是range(41)

    【讨论】:

      【解决方案2】:

      问题在于:

      filenamelist = [str(filenamelist) + "frameinstance" + str(i)]
      

      filenamelist 是一个列表,str(filenamelist) 将为您提供该列表的字符串表示形式:括号[],包围该列表中每个项目的字符串表示形式(使用repr)。让我们看看它是如何扩展的:

      []
      ['[]frameinstance0']
      ["['[]frameinstance0']frameinstance1"]
      ['["[\'[]frameinstance0\']frameinstance1"]frameinstance2']
      ['[\'["[\\\'[]frameinstance0\\\']frameinstance1"]frameinstance2\']frameinstance3']
      ['[\'[\\\'["[\\\\\\\'[]frameinstance0\\\\\\\']frameinstance1"]frameinstance2\\\']frameinstance3\']frameinstance4']
      

      哎呀。字符串的字符串表示包括它的引号,在某些时候必须用反斜杠转义。反斜杠也必须用另一个反斜杠转义,导致反斜杠指数增长。让我们算一下:

      • 第三个字符串表示形式有 2 个单引号和 0 个反斜杠
      • 每次新迭代都添加 2 个单引号,每个反斜杠添加 1 个反斜杠,每个单引号添加 1 个反斜杠

      在循环 40 次之后,您最终会得到一个列表,其中包含一个包含 2740 亿个反斜杠的字符串,这需要大量的反斜杠来适应内存。

      这里的问题是将列表转换为字符串以将另一个字符串连接到它;您可能打算将列表连接到列表而不是字符串连接到字符串。这是可行的:

      filenamelist = filenamelist + ["frameinstance" + str(i)]
      

      不过,通常情况下,您会使用列表的 append 方法在适当位置添加一项。

      filenamelist.append("frameinstance" + str(i))
      

      现在是注意 Python 有一些有用的字符串格式化工具来将数字(以及更多)格式化为字符串的好时机:

      "frameinstance%d" % (i,)
      "frameinstance{}".format(i)
      f"frameinstance{i}"  # Python 3.6+
      

      并预览一下您将来可能会知道如何编写此内容的简短方法!

      filenamelist = [f"frameinstance{i}" for i in range(0, 40)]
      

      【讨论】:

        【解决方案3】:

        您需要将对象添加到列表中

        filenamelist = []
        i = 0
        for i in range(0,40):
            filenamelist.append("frameinstance" + str(i))
        

        【讨论】:

          【解决方案4】:

          你的第一关真的很接近。需要考虑的几点:

          1. 您不需要初始化filenamelisti

          2. 您可以使用列表推导将 for 循环放入列表构造 filenamelist = ["frameinstance{}".format(i) for i in range(41)]

          【讨论】:

            【解决方案5】:
            ['frameinstance{}'.format(i) for i in range(0,41)]
            
            1. 范围(开始,结束)不包括结束 range(0, 40) 将在 39 结束
            2. 您需要构造一个列表而不是字符串,建议使用列表推导式。

            【讨论】:

              【解决方案6】:

              试试这个:

              filenamelist = []
              for i in range(41):
                  filenamelist.append("frameinstance%s.png" % i)
              

              或者更多pythonic(更快,for循环在python中很慢):

              filenamelist = ["frameinstance%s.png" % i for i in range(41)]
              

              您收到 MemoryError 是因为您反复将列表添加到自身导致您耗尽 RAM :P。

              【讨论】:

                猜你喜欢
                • 2010-10-16
                • 2011-12-04
                • 1970-01-01
                • 1970-01-01
                • 2011-03-27
                • 2021-03-11
                • 2015-08-09
                • 2021-05-28
                • 1970-01-01
                相关资源
                最近更新 更多