3

The output is: Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1}) Can I remove the "Counter" word?

from collections import Counter

word = "hello"

print(Counter(word))
okden
  • 63
  • 3
  • You can convert a `Counter` back to a normal dictionary, if that's what you mean? It's covered [in the docs](https://docs.python.org/3/library/collections.html#collections.Counter). – jonrsharpe Mar 17 '19 at 13:30
  • @jonrsharpe I'm pretty sure the order will be lost in Python < 3.7, though – DeepSpace Mar 17 '19 at 13:33
  • 2
    @DeepSpace *what* order? `Counter` isn't ordered either. – jonrsharpe Mar 17 '19 at 13:34
  • @jonrsharpe it is (at least its `str` representation): `print(Counter('aaabbc')) # Counter({'a': 3, 'b': 2, 'c': 1})` – DeepSpace Mar 17 '19 at 13:36
  • related https://stackoverflow.com/questions/20316299/formatting-output-of-counter – Jean-François Fabre Mar 17 '19 at 13:38
  • 1
    @DeepSpace that's an implementation detail that's not even mentioned in the docs, it's because they call `most_common` instead of just `items` [in the `__repr__`](https://github.com/python/cpython/blob/3.7/Lib/collections/__init__.py#L707). – jonrsharpe Mar 17 '19 at 13:39
  • @jonrsharpe Fair enough (I'm a big fan of "that's an implementation detail" :D) but OP should be aware of this fact – DeepSpace Mar 17 '19 at 13:40

3 Answers3

7

To convert a Counter back into a normal dictionary, just do this:

d = dict(Counter(word))

Now it'll look as usual when you print it:

print(d)

It really doesn't make any difference, though. Counter is a dictionary after all. I guess it's ok if you want it to look pretty when printing it.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • But the order will be lost (at least in Python < 3.7): `print(dict(Counter('aaabbc'))) # {'c': 1, 'a': 3, 'b': 2}` – DeepSpace Mar 17 '19 at 13:34
  • 1
    @DeepSpace that's ok, you must not count on the order of a dictionary, it's not guaranteed for all Python versions. Besides, that's not a requirement in the question, and anyway `Counter` didn't preserve the order, either. – Óscar López Mar 17 '19 at 13:36
  • 1
    Dictionaries are not meant for ordered set of values. – Irfanuddin Mar 17 '19 at 13:40
  • @ÓscarLópez See my comment to jonrsharpe. It's an implementation detail of how `Counter.__repr__` is implemented but it is at least worth mentioning. – DeepSpace Mar 17 '19 at 13:42
  • 1
    @IrfanuddinShafi No, they aren't (usually). **But** when printing `Counter` you **do** get an ordered output (follow the rest of the comments, `Counter.__repr__` is implemented using `.most_common` in most if not all Python implementations). It is at least worth mentioning that when converting to a "normal" `dict` this ordered output will be lost – DeepSpace Mar 17 '19 at 13:44
  • @DeepSpace but again, that's not a requirement in the question. The downvote is unwarranted. – Óscar López Mar 17 '19 at 13:46
  • @ÓscarLópez How do you know? OP did not mention it. – DeepSpace Mar 17 '19 at 13:47
  • 1
    @DeepSpace you've been in SO long enough to know it: if it's not explicitly stated in the question, it's not a requirement, otherwise OP wouldn't have accepted this answer. It's incorrect to assume a non-written requirement, unless explicitly stated. And `Counter` doesn't preserve the input order, so there was no order to preserve in the first place. You're depending on an implementation detail. – Óscar López Mar 17 '19 at 13:53
2

Of course, you can pass the object to json.dumps. json only sees the dictionary, not the subclass

from collections import Counter
import json

word = "hello"
c = Counter(word)

print(json.dumps(c))

result:

{"l": 2, "o": 1, "h": 1, "e": 1}

that avoids to create a copy as a basic dictionary just to display it properly. More ways to print the contents using just loops on key/values and prints: Formatting output of Counter

Another way is to force basic dict representation method:

print(dict.__repr__(Counter(word)))

result:

{'h': 1, 'o': 1, 'e': 1, 'l': 2}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

You can remove the string 'Counter()' with the function strip():

c = Counter('AA')

print(repr(c).strip('Counter()'))
# {'A': 2}

or

print(c.__repr__().strip('Counter()')) 
# {'A': 2}

Alternatively you can use string slicing. It should be more efficient (according to @jonrsharpe):

print(c.__repr__()[8:-1])) 
# {'A': 2}
Mykola Zotko
  • 15,583
  • 3
  • 71
  • 73