2017-04-03 29 views
2

添加密鑰如果計數器對象的鍵的類型是str,即:添加單個字符櫃檯

我可以這樣做:

>>> vocab_counter = Counter("the lazy fox jumps over the brown dog".split()) 

>>> vocab_counter = Counter({k+u"\uE000":v for k,v in vocab_counter.items()}) 
>>> vocab_counter 
Counter({'brown\ue000': 1, 
     'dog\ue000': 1, 
     'fox\ue000': 1, 
     'jumps\ue000': 1, 
     'lazy\ue000': 1, 
     'over\ue000': 1, 
     'the\ue000': 2}) 

這將是一個快速和/或pythonic的方式來添加一個字符到所有的鍵?

上述方法是否可以通過將字符附加到所有鍵來實現最終計數器的唯一方法?是否有其他方式來實現相同的目標?

+3

我認爲你這樣做的方式似乎很不錯......你期待什麼樣的改進?所用的時間?代碼行? – Shadow

+0

不是代碼行,只是想知道是否有更好的方法。多次遍歷所有密鑰並不是非常理想的。也許我必須將其轉儲到數據框或numpy數組,然後再讀回到計數器。 – alvas

+1

我不認爲這會更好......這種方式將涉及創建拆分字符串的列表,操縱它們中的每一個,然後對它們進行計數。目前它正在關閉的方式只涉及每個獨特的詞 - 所以如果計算一本小說它會更乾淨和有效率(無論如何,我認爲)唯一的改變是創建一個字典,而不是在你最後一步計數器,因爲你不需要再計算了(我假設) – Shadow

回答

1

更好的方法是在創建計數器對象之前添加該字符。如果這是不可能的創建計數器可以覆蓋Counter對象,以添加特殊字符during setting the values for keys之前修改的話

In [15]: vocab_counter = Counter(w + u"\uE000" for w in "the lazy fox jumps over the brown dog".split()) 

In [16]: vocab_counter 
Out[16]: Counter({'the\ue000': 2, 'fox\ue000': 1, 'dog\ue000': 1, 'jumps\ue000': 1, 'lazy\ue000': 1, 'over\ue000': 1, 'brown\ue000': 1}) 

:使用內Counter發電機表達你可以做到這一點。

1

唯一的其他優化的方式我能想到的是使用Counter是追加字符一個子類,當鑰匙插入:

from collections import Counter 


class CustomCounter(Counter): 
    def __setitem__(self, key, value): 
     if len(key) > 1 and not key.endswith(u"\uE000"): 
      key += u"\uE000" 
     super(CustomCounter, self).__setitem__(key, self.get(key, 0) + value) 

演示:

>>> CustomCounter("the lazy fox jumps over the brown dog".split()) 
CustomCounter({u'the\ue000': 2, u'fox\ue000': 1, u'brown\ue000': 1, u'jumps\ue000': 1, u'dog\ue000': 1, u'over\ue000': 1, u'lazy\ue000': 1}) 
# With both args and kwargs 
>>> CustomCounter("the lazy fox jumps over the brown dog".split(), **{'the': 1, 'fox': 3}) 
CustomCounter({u'fox\ue000': 4, u'the\ue000': 3, u'brown\ue000': 1, u'jumps\ue000': 1, u'dog\ue000': 1, u'over\ue000': 1, u'lazy\ue000': 1}) 
+2

演示中的CustomCounter包含條目'u'the \ ue000':1',它應該具有值2,所以看起來好像這個解決方案有錯誤。 – Felix

+0

@Felix Oopsy!固定。 –

1

最短的路我用的是,

vocab_counter = Counter("the lazy fox jumps over the brown dog".split()) 
for key in vocab_counter.keys(): 
    vocab_counter[key+u"\uE000"] = vocab_counter.pop(key) 
+0

''\ ue000''應該在每個新鑰匙的末尾,而不是前面。 –

+0

耶!您可以將其視爲錯字:P – DexJ

+0

現在已經修復了,我認爲這是這裏唯一的無錯答案。我不認爲這種方法比問題中的更好,但至少不會更糟。 –

0

你可以用字符串操作來做到這一點:

text = 'the lazy fox jumps over the brown dog' 
Counter((text + ' ').replace(' ', '_abc ').strip().split())