【问题标题】:Python: List Dictionary ComprehensionPython:列表字典理解
【发布时间】:2012-12-09 20:11:11
【问题描述】:

我有以下代码:

letters = 'defghijklmno'
K = {letters[i]:(i*i-1) for i in range(len(letters))}

我知道我正在迭代字母的序列变量以及如何计算值,但我对如何将键设置为字符串的各个字符感到困惑。特别是因为我有字母被索引为我的键。基本上,我只是想弄清楚python如何评估这个表达式

【问题讨论】:

    标签: python dictionary iteration


    【解决方案1】:

    dict 理解基本上是以下的同义词:

    k = {}
    for i in range(len(letters)):
        k[letters[i]] = i*i - 1
    

    不同之处在于它创建了一个新的作用域而不是使用外部作用域:

    >>> letters = 'defghijklmno'
    >>> K = {letters[i]:(i*i-1) for i in range(len(letters))}
    >>> i          # was defined in an inner scope
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'i' is not defined
    >>> k = {}
    >>> for i in range(len(letters)):
    ...     k[letters[i]] = i*i - 1
    ... 
    >>> i     # still defined!
    11
    

    【讨论】:

      【解决方案2】:

      解释:

      >>> letters = 'defghijklmno'
      >>> range(len(letters))
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
      

      这意味着,那个

      >>> [letters[i] for i in range(len(letters))]
      ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
      

      同时

      >>> [(i*i-1) for i in range(len(letters))]
      [-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]
      

      因此,您的字典理解构建了对 'd':-1, 'e':0, 'f':3, ... (等)的字典。

      【讨论】:

        【解决方案3】:

        嗯,首先,这是一种相当糟糕的做法。在 Python 中按索引循环是一种非常糟糕的做法(它更慢,而且读起来很糟糕),所以更好的方法是:

        letters = 'defghijklmno'
        K = {letter: (i*i-1) for i, letter in enumerate(letters)}
        

        这只是一个简单的dictionary comprehension。当我们遍历一个字符串时,我们会得到组成它的各个字符。我们使用 enumerate() 内置函数给我们匹配的数字,然后生成一个字典,从字母到数字的平方,减一。

        如果您正在为理解本身而苦苦挣扎,它相当于一个 for 循环(除了更快),我建议您观看 my video 以获得完整的解释,其中包含字典理解的示例以及它的表亲(列表/集合理解和生成器)表达式)。

        【讨论】:

          【解决方案4】:

          要理解它,看看发生的事情的各个部分会有所帮助。 for i in range(len(letters)) 循环不会遍历字母的单个字符,而是遍历字符串的 indizes。那是因为您可以使用它们的索引访问字符串的单个字符。所以letters[0] 指第一个字符,letters[1] 指第二个字符,letters[len(letters)-1] 指最后一个字符。

          那么,让我们分别看一下字典的键:

          >>> [letters[i] for i in range(len(letters))]
          ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o']
          

          因此,您可以按原始顺序单独获取所有字母。

          现在,让我们看看字典的值:

          >>> [(i*i-1) for i in range(len(letters))]
          [-1, 0, 3, 8, 15, 24, 35, 48, 63, 80, 99, 120]
          

          所以,现在我们既有键又有值;字典解析现在所做的只是将这些键链接到值 - 按照上面的顺序。

          【讨论】:

            【解决方案5】:

            第二行是字典理解。它类似于普通的列表推导式或生成器表达式,不同之处在于它生成键值对,然后用于形成字典。

            代码大致相当于

            letters = 'defghijklmno'
            K = {}
            for i in range(len(letters)):
                key = letters[i]
                val = (i*i-1)
                K[key] = val
            

            【讨论】:

              【解决方案6】:

              你可以将字典理解重写为循环

              K = {} # empty dict
              for i in range(len(letters)): # i goes from 0 to 11
                  K[letters[i]] = i*i-1
              

              所以在你拥有的单次迭代中

              K['d'] = -1
              K['e'] = 0
              K['f'] = 3
              # ...
              

              等等。 dict 理解只是编写此循环的一种更短(并且在大多数 Python 程序员看来)更优雅的方式。

              【讨论】:

                【解决方案7】:

                对于从i == 0i == 11letters 中最后一个字母的索引)的每个i,都会将一个条目添加到结果字典中,其中键为letters[i],其关联值为@987654326 @。这给出了:

                K['d'] == -1
                K['e'] == 0
                K['f'] == 3
                

                等等。

                【讨论】:

                  【解决方案8】:

                  本质上,您实际上并没有迭代letters 的字母;相反,您通过将i0 更改为1,到2,...,到11 来迭代letters长度。当您改变i 时,您将创建一个字典条目,其键是letters 的第i 个字母,其值为i*i - 1

                  换句话说,您创建了一个字典,其中的每个条目由来自letters 的字母(键)k 与等于k 的指数平方减去1 的值配对。

                  您可以用简单的英语阅读字典理解为:所有字母(键)k 的字典,来自 letters,索引为 i,与值 i*i - 1 配对。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-03-14
                    • 2021-03-12
                    • 1970-01-01
                    • 2018-03-18
                    • 2020-10-18
                    • 1970-01-01
                    相关资源
                    最近更新 更多