使用if语句理解Python字典,但if语句包含字典本身

使用if语句理解Python字典,但if语句包含字典本身,python,dictionary,if-statement,syntax,Python,Dictionary,If Statement,Syntax,我想为一串字母创建一个字典,它们的键是唯一的字母,值是字母第一次出现的索引。例如:word='mississippi',正确答案应该是{'m':0,'i':1,'s':2,'p':8} 我试着写“pythonic”代码: dict = {word[i]:i for i in range(len(word)) if word[i] not in dict.keys()} 然而,我得到的是:{'I':10,'m':0,'p':9,'s':6}, 这就好像dict没有更新,在调用if语句时仍然是

我想为一串字母创建一个字典,它们的键是唯一的字母,值是字母第一次出现的索引。例如:word='mississippi',正确答案应该是{'m':0,'i':1,'s':2,'p':8}

我试着写“pythonic”代码:

dict = {word[i]:i  for i in range(len(word))  if word[i] not in dict.keys()}
然而,我得到的是:{'I':10,'m':0,'p':9,'s':6}, 这就好像dict没有更新,在调用if语句时仍然是空的

正常的for循环做了正确的事情:

for i in range(len(word)):

    if word[i] not in first_apperance_dict.keys():

        dict[word[i]]=i
输出:{'i':1,'m':0,'p':8,'s':2}


那为什么呢?对于这个问题有一个pythonic优雅的代码吗?一般来说,我应该只在列表/字典理解中的if语句中添加“静态”变量吗?

您不能使用理解来引用它正在创建的dict,因为dict直到理解完成后才创建

一般来说,你不能用理解来做你正在做的事情。在理解中,每个值应该只依赖于迭代中的一个值。但在您的计算中,每个值取决于所有先前值的结果(通过它们对创建的dict的影响)

对于您的特定示例,这里有一种更简单的方法,因为您想要的结果实际上并不依赖于以前的值。您只需要单词中每个字符的第一次出现,这可以直接完成:

>>> {char: word.index(char) for char in word}
{'i': 1, 'm': 0, 'p': 8, 's': 2}
在此版本中,字符的后续出现“覆盖”了早期出现的值,但它们覆盖了相同的值,因此没有效果。更好的版本是:

>>> {char: word.index(char) for char in set(word)}
{'i': 1, 'm': 0, 'p': 8, 's': 2}

这只对单词中的唯一字符进行迭代,而不是对所有字符进行迭代。

您不能使用理解来引用它正在创建的dict,因为直到理解完成后才创建dict

一般来说,你不能用理解来做你正在做的事情。在理解中,每个值应该只依赖于迭代中的一个值。但在您的计算中,每个值取决于所有先前值的结果(通过它们对创建的dict的影响)

对于您的特定示例,这里有一种更简单的方法,因为您想要的结果实际上并不依赖于以前的值。您只需要单词中每个字符的第一次出现,这可以直接完成:

>>> {char: word.index(char) for char in word}
{'i': 1, 'm': 0, 'p': 8, 's': 2}
在此版本中,字符的后续出现“覆盖”了早期出现的值,但它们覆盖了相同的值,因此没有效果。更好的版本是:

>>> {char: word.index(char) for char in set(word)}
{'i': 1, 'm': 0, 'p': 8, 's': 2}

这只对单词中的唯一字符进行迭代,而不是对所有字符进行迭代。

已经有了一个很好的解释@BrenBarn。我只是演示如何使用
find()
方法。此方法返回给定
字符串中
字符的第一个出现索引

>>> word = 'mississippi'
>>> {w:word.find(w) for w in set(word)}
{'i': 1, 'p': 8, 's': 2, 'm': 0}

@BrenBarn已经给出了一个很好的解释。我只是演示如何使用
find()
方法。此方法返回给定
字符串中
字符的第一个出现索引

>>> word = 'mississippi'
>>> {w:word.find(w) for w in set(word)}
{'i': 1, 'p': 8, 's': 2, 'm': 0}