例如,如果我提供字符串'aaaaaabbbbcccc'
和n = 2
,则应返回[('a',6),('b',4)]
。我已经用这种方式尝试过了:
def top_chars(word, n):
list1=list(word)
list3=[]
list2=[]
list4=[]
set1=set(list1)
list2=list(set1)
def count(item):
count=1
for x in word:
if x in word:
count+=item.count(x)
list3.append(count)
return count
list2.sort(key=count)
list3.sort()
list4=list(zip(list2,list3))
list4.reverse()
list4.sort(key=lambda list4: ((-list4[1]),(list4[0])), reverse=True)
return list4[0:n]
但对于top_chars ("app", 1)
,它返回了输出[('p', 1)]
,其中计数错误。
答案 0 :(得分:1)
如果您想在不使用collections.Counter
的情况下执行此操作,请先查看您的代码:
list1=list(word)
set1=set(list1)
list2=list(set1)
除了非描述性的名称(您应该避免使用)之外,您基本上可以将其压缩到characters = list(set(word))
以获取单词中所有字符的列表而不重复。由于word
是一个字符串,因此在其上调用set()
将自动按字符迭代字符串。
接下来,在count
功能中,您检查if x in word
虽然您明确地在x in word
进行了互动。因此无论x
是什么,它总是在word
。所以你可以退房。然后,当你实际增加计数时,你可以通过x
的出现来增加它 - 这是原始单词中所有字符 - 在传递的item
内部。当您使用该函数作为单词(唯一)字符列表的排序键时,您将基本上计算单个字符串中单词每个字符的出现次数,表示当前唯一字符。因此,如果item
和x
都是单个字符,那么实际上count
会增加x == item
,如果list3
- 尽管是非常奇怪的方式。接下来 - 仍然在原始字符的循环内 - 将该计数追加到word
并返回计数。
那到目前为止发生了什么?您查看了item
的第一个字符,并检查count
是否等于该字符。如果是这种情况,请将1
从2
增加到1
,否则请将其保留在count
。然后你只需保留count = 1
并从函数返回。因此,你永远不会真正看到这个单词的其他字符,这就解释了为什么你的计数总是1或2。
如果你保持循环运行,然后只返回(并附加计数),那么它可以正常工作(即从这两行中删除两个缩进级别)。但是,当你从list2
开始时,你总是太多了,所以你应该从0开始。
继续,您现在可以使用相同的值对list3
和defaultdict
进行排序,以便它们排成一行。通过构建列表,这很幸运,但它仍然有点奇怪。然后,您将已排序的列表压缩并反转订单。然后你做一些我并不理解的事情:你取出已经按字符数反向排序的列表,并按否定计数对它进行排序颠倒 。对负计数进行反向排序基本上是正常排序的正计数;所以你按升序排序。这将为您提供所需内容的反向结果,并且实际上也不需要,因为列表在压缩后已经排序。
无论如何,你的代码还有很多需要改进的地方。首先,即使您没有使用计数器,您仍应使用字典来存储计数。我假设您也可能不使用counts = {}
for character in word:
# if we haven’t seen the character yet, we need to
# initialize it in our dictionary first (this is
# essentially what defaultdict does)
if character not in counts:
counts[character] = 0
# we have seen `character` once more, so increment count
counts[character] += 1
,因此我们将自己构建功能。不是创建单词中所有字符的列表,然后计算单词在单词中出现的频率,我们只需循环一次通过单词并记下我们看到的每个字符:
{'b': 4, 'c': 4, 'a': 6}
我们需要做的就是实际计算字符。对于该示例单词,我们现在将其作为我们的字典:n
。
所以现在,我们只需从那里找到zip
最大的元素。你的countsList = list(counts.items())
# sort the list in reverse by the second element
countsList.sort(key=lambda x: (x[1], x[0]), reverse=True)
想法实际上对此非常有益;所以让我们从dict创建一个元组列表,然后我们可以对它进行排序:
n
现在我们已经准备好了最终列表,然后我们可以获取第一个[('a', 6), ('c', 4)]
元素来获取结果def top_words (word, n):
counts = {}
for character in word:
if character not in counts:
counts[character] = 0
counts[character] += 1
countsList = list(counts.items())
countsList.sort(key=lambda x: (x[1], x[0]), reverse=True)
return countsList[:n]
。
总的来说,这就是我们的功能:
collections.Counter
像这样使用,并与>>> top_words('aaaaaabbbbcccc', 2)
[('a', 6), ('c', 4)]
>>> top_words('app', 1)
[('p', 2)]
>>> Counter('aaaaaabbbbcccc').most_common(2)
[('a', 6), ('b', 4)]
>>> Counter('app').most_common(1)
[('p', 2)]
进行比较:
{{1}}