字典理解从循环产生不同的结果

时间:2018-06-06 12:12:47

标签: python python-3.x dictionary

循环检查单词是否包含单词中的字母,如下所示。

hand = {'h': 1, 'e': 1, 'l': 2, 'o': 1}
word = 'hello'

extra_hand = hand.copy()

for letter in word: 
    extra_hand[letter] -= 1

>> extra_hand
{'h': 0, 'e': 0, 'l': 0, 'o': 0}

然后,我尝试转换为字典理解。它看起来应该是这样的。

hand = {'h': 1, 'e': 1, 'l': 2, 'o': 1}
word = 'hello'
extra_hand = {letter:hand[letter] - 1 for letter in word}

>>extra_hand
{'h': 0, 'e': 0, 'l': 1, 'o': 0}

正如你所看到的,结果是不同的,l是1,这是不正确的。我怀疑'l'是从没有变异的手字典对象派生的。所以,它只做了两次2-1并且变为1而不是2-1和1-1。

我该怎样做才能解决字典理解?

3 个答案:

答案 0 :(得分:3)

字典理解不能以这种递归方式使用。当迭代word时,它无法持续更新项目。

另一种想到这一点的方法是,在整个理解完成之前,字典的键和值不可用于操作。

您可以将字典理解视为复制下面的for循环。与for循环一样,您将设置值而不是添加到先前分配给键的值。

for letter in word:
    extra_hand['letter'] = hand['letter'] - 1

你的循环非常好,不需要使用词典理解。

作为替代方案,如果您只想计算非零计数,可以使用collections.Counter

from collections import Counter

hand = {'h': 1, 'e': 1, 'l': 2, 'o': 1}
word = 'hello'
res = Counter(hand) - Counter(word)

# Counter()

hand = {'h': 1, 'e': 2, 'l': 2, 'o': 1}
word = 'hello'
res = Counter(hand) - Counter(word)

# Counter({'e': 1})

答案 1 :(得分:1)

你的两种方法并不一样。如果字典理解方法将在循环中进行转换,那么你将得到

hand = {'h': 1, 'e': 1, 'l': 2, 'o': 1}
word = 'hello'
extra_hand = {}
for letter in word:
    extra_hand[letter] = hand[letter] - 1

因此,hand['l']永远不会更改,因此,当循环到达第二个2时,它仍然是l。这就是为什么两次都获得1值的原因。

在我看来,循环变体非常好。

答案 2 :(得分:1)

extra_hand = {letter:hand[letter] - 1 for letter in word}

相当于:

for letter in word: 
    extra_hand[letter] = hand[letter] - 1

而不是:

for letter in word: 
    extra_hand[letter] -= 1

在第一种情况下,extra_hand['l']等于1,而在第二种情况下,您减去1两次(得到0)。