0

I'm trying to build a simple program that counts how many entries are in a file for a specific hour. I'm targeting the hour-part of the timestamp in the txt-file and counting each one. That all works well but when I print the result I want it to order the hours from 00, 01 and so on up to 22, 23.

This is my code:

hour = []
for x in hour:
    hour.append(x[10:12]) #To get just the hour-part of the timestamp.

hour_sorted = (sorted(hour)) #Now the hours are sorted from 00 to 23, all good so far.

counts = Counter(hour_sorted)

for number in counts:
    if number in counts:
        print(number + ' ' + str(counts[number]))

The problem is that now prints all the hours out of order.

Output example:

    10    3
    00    2
    12    2
    21    3

and so on. I want it like this:

    00    2
    10    3
    12    2
    21    3

Any ideas what I'm doing wrong?

Right leg
  • 16,080
  • 7
  • 48
  • 81
pythonnoob
  • 29
  • 3
  • 1
    See https://stackoverflow.com/questions/35446015/creating-an-ordered-counter. – dedObed Dec 12 '19 at 10:03
  • Hey, could you specify which version of Python your are using ? `collections.Counter` is a dictionary object, which ordering has changed a lot between python 2 and 3 – LoicM Dec 12 '19 at 10:05
  • 3
    Also, I think the `if` condition inside `for` loop is redundant. – Raj Dec 12 '19 at 10:06

2 Answers2

2

The data structure that underlies Counter is a dict. You can see this in CPython's sources. A dict in Python is a hashmap, which is, generally speaking, an unordered structure. More specifically, it does not preserve the order of insertion.

Therefore, when iterating over the elements of a Counter instance, you won't get them in the same order as you stored them.

However, from Python 3.6, dicts are naturally ordered, so you'd get the behaviour you expect. I'm running Python 3.7, and if I populate the hour list, that's what I get:

00 2
10 3
12 1
21 1

The entries are printed in the order of insertion, that is, the order of hour after it's been sorted.

If you're not running Python 3.6 or later however, you must iterate over hour after it's been sorted so as to take that ordering into account:

hour_sorted = (sorted(hour))
counts = Counter(hour_sorted)

for hour in hour_sorted:
    print(hour, counts[hour])
Right leg
  • 16,080
  • 7
  • 48
  • 81
  • Thanks for all the help! I will try this as soon as I get home :) – pythonnoob Dec 12 '19 at 13:29
  • 1
    Had to remote to my computer and try it immediately. When I ran the same code in python 3 it all worked like a charm! Thanks for the fast and great help! – pythonnoob Dec 12 '19 at 13:33
0

you need to sort Counter object before youre for loop:

...
counts  = sorted(counts.items())
...
Dishin H Goyani
  • 7,195
  • 3
  • 26
  • 37