无需使用计数器即可获取大多数出现的字符及其数

时间:2014-01-23 09:58:10

标签: python count

例如,如果我提供字符串'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)],其中计数错误。

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内部。当您使用该函数作为单词(唯一)字符列表的排序键时,您将基本上计算单个字符串中单词每个字符的出现次数,表示当前唯一字符。因此,如果itemx都是单个字符,那么实际上count会增加x == item,如果list3 - 尽管是非常奇怪的方式。接下来 - 仍然在原始字符的循环内 - 将该计数追加到word并返回计数。

那到目前为止发生了什么?您查看了item第一个字符,并检查count是否等于该字符。如果是这种情况,请将12增加到1,否则请将其保留在count。然后你只需保留count = 1并从函数返回。因此,你永远不会真正看到这个单词的其他字符,这就解释了为什么你的计数总是1或2。

如果你保持循环运行,然后只返回(并附加计数),那么它可以正常工作(即从这两行中删除两个缩进级别)。但是,当你从list2开始时,你总是太多了,所以你应该从0开始。

继续,您现在可以使用相同的值对list3defaultdict进行排序,以便它们排成一行。通过构建列表,这很幸运,但它仍然有点奇怪。然后,您将已排序的列表压缩并反转订单。然后你做一些我并不理解的事情:你取出已经按字符数反向排序的列表,并按否定计数对它进行排序颠倒 。对负计数进行反向排序基本上是正常排序的正计数;所以你按升序排序。这将为您提供所需内容的反向结果,并且实际上也不需要,因为列表在压缩后已经排序。

无论如何,你的代码还有很多需要改进的地方。首先,即使您没有使用计数器,您仍应使用字典来存储计数。我假设您也可能不使用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}}