Python dict.setdefault()如何计算字符数?

Python dict.setdefault()如何计算字符数?,python,dictionary,Python,Dictionary,我从《用Python自动化无聊的东西》一书中得到了这段代码,我不明白setdefault()方法如何计算唯一字符的数量 代码: 根据这本书,setdefault()方法在字典中搜索关键字,如果找不到,则更新字典,如果找不到则什么也不做。 但是我不理解setdefault的计数行为以及它是如何完成的 输出: {' ': 13, ',': 1, '.': 1, 'A': 1, 'I': 1, 'a': 4, 'c': 3, 'b': 1, 'e': 5, 'd': 3, 'g': 2, 'i':

我从《用Python自动化无聊的东西》一书中得到了这段代码,我不明白
setdefault()
方法如何计算唯一字符的数量

代码:

根据这本书,setdefault()方法在字典中搜索关键字,如果找不到,则更新字典,如果找不到则什么也不做。 但是我不理解
setdefault
的计数行为以及它是如何完成的

输出:

{' ': 13, ',': 1, '.': 1, 'A': 1, 'I': 1, 'a': 4, 'c': 3, 'b': 1, 'e': 5, 'd': 3, 'g': 2,
 'i': 6, 'h': 3, 'k': 2, 'l': 3, 'o': 2, 'n': 4, 'p': 1, 's': 3, 'r': 5, 't': 6, 'w': 2, 'y': 1}
请给我解释一下。

在您的示例中,setdefault()相当于此代码

if character not in count:
    count[character] = 0
这是(可以说)做同样事情的更好方式:

from collections import defaultdict
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'
count = defaultdict(int)
for character in message:
    count[character] = count[character] + 1
print(count)
它之所以有效,是因为默认int为0

更好的方法如下:

from collections import Counter
print(Counter(
    'It was a bright cold day in April, '
     'and the clocks were striking thirteen.'))

至少在这种情况下,最好使用defaultdict

from collections import defaultdict
count = defaultdict(int)
for character in message:
  count[character] += 1
defaultdict使用无参数函数构造,该函数创建任何默认值的实例。如果某个键不存在,则此函数为其提供一个值,并将该键、值插入字典中。由于int()返回0,因此在本例中已正确初始化。如果您希望将它初始化为其他值n,那么您可以执行以下操作

count = defaultdict(lambda : n)

我用的是同一本教科书,我也有同样的问题。提供的答案比所讨论的示例更复杂,因此它们实际上并没有解决这个问题:上面的问题是-代码如何理解它应该计算出现的次数。事实证明,这并不真的“算数”。它只是不断更改值,直到停止。经过漫长而痛苦的研究,我对自己解释如下:

message='It was a bright,\
cold day in April,\
and the clocks were \
striking thirteen.'
count={}   # "count" is set as an empty dictionary, which we want to fill out
for character in message:  # for each character, do the following:
    count.setdefault(character,0)  # if the character is not there,
                                   # take it from the message above
                                   # and set it in the dictionary
                                   # so the new key is a letter (e.g. 'a') and value is 0
                                   # (zero is the only value that we can set by default
                                   # otherwise we would gladly set it to 1 (to start with the 1st occurrence))
                               # but if the character already exists - this line will do nothing! (this is pointed out in the same book, page 110) 
                               # the next time it finds the same character
                               # - which means, its second occurrence -
                               # it won't change the key (letter)
                               # But we still want to change the value, so we write the following line:
    count[character]=count[character]+1  # and this line will change the value e.g. increase it by 1
                                         # because "count[character]",
                                         # is a number,  e.g. count['a'] is 1 after its first occurrence
                                         # This is not an "n=n+1" line that we remember from while loops
                                         # it doesn't mean "increase the number by 1
                                         # and do the same operation from the start"
                                         # it simply changes the value (which is an integer) ,
                                         # which we are currently processing in our dictionary, by 1
                                # to summarize: we want the code to go through the characters
                                # and only react to the first occurence of each of them; so
                                # the setdefault does exactly that; it ignores the values;
                                # second, we want the code to increase the value by 1
                                # each time it encounters the same key; 
                                # So in short:
                                # setdefault deals with the key only if it is new (first occurence)
                                 # and the value can be set to change at each occurence,
                                 # by a simple statement with a "+" operator
                                 # the most important thing to understand here is that
                                 # setdefault ignores the values, so to speak,
                                 # and only takes keys, and even them only if they are newly introduced.
print(count)   # prints the whole obtained dictionary

@egon的回答非常好,它回答了这里提出的疑问。我只是对代码做了一点修改,希望它现在很容易理解

message = 'naga'
count = {}
for character in message:
    count.setdefault(character,0)
    print(count)
    count[character] = count[character] + 1
    print(count)  
print(count)

   and the output will be as follows 

  {'n': 0} # first key and value set in count 
  {'n': 1} # set to this value when count[character] = count[character] + 1 is executed.
  {'n': 1, 'a': 0} # so on 
  {'n': 1, 'a': 1}
  {'g': 0, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 2}
  {'g': 1, 'n': 1, 'a': 2}

setdefault
不计数,但确保以0开始计数。试着移除它,看看会发生什么。
message = 'naga'
count = {}
for character in message:
    count.setdefault(character,0)
    print(count)
    count[character] = count[character] + 1
    print(count)  
print(count)

   and the output will be as follows 

  {'n': 0} # first key and value set in count 
  {'n': 1} # set to this value when count[character] = count[character] + 1 is executed.
  {'n': 1, 'a': 0} # so on 
  {'n': 1, 'a': 1}
  {'g': 0, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 1}
  {'g': 1, 'n': 1, 'a': 2}
  {'g': 1, 'n': 1, 'a': 2}
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'
count = {} #This is an empty dictionary. We will add key-value pairs to this dictionary with the help of the following lines of code (The for-loop and its code block).

for character in message: #The loop will run for the number of single characters (Each letter & each space between the words are characters) in the string assigned to 'message'.
                          #That means the loop will run for 73 times.
                          #In each iteration of the loop, 'character' will be set to the current character of the string for the running iteration.
                          #That means the loop will start with 'I' and end with '.'(period). 'I' is the current character of the first iteration and '.' is the current character of the last iteration of the for-loop.

    count.setdefault(character, 0) #If the character assigned to 'character' is not in the 'count' dictionary, then the character will be added to the dictionary as a key with its value being set to 0.
    count[character] = count[character] + 1 #The value of the key (character added as key) of 'count' in the running iteration of the loop is incremented by one.
                                            #As a result of a key's value being incremented, we can track how many times a particular character in the string was iterated.
                                            #^It's because the existing value of the existing key will be incremented by 1 for the number of times the particular character is iterated.
                                            #The accuracy of exactly how many times a value should be incremented is ensured because already existing keys in the dictionary aren't updated with new values by set.default(), as it does so only if the key is missing in the dictionary. 

print(count) #Prints out the dictionary with all the key-value pairs added.
             #The key and its value in each key-value pair represent a specific character from the string assigned to 'message' and the number of times it's found in the string, respectively.