Counter in Python

Counter is a specialized dictionary class from the collections module in Python's standard library. It is designed for counting hashable objects.

What it is

A Counter object maps items to the number of times they appear. It behaves like a dictionary where the default value for missing keys is 0 instead of raising a KeyError.

from collections import Counter

# Count items in a list
ports = [80, 443, 80, 8080, 443, 80]
counts = Counter(ports)

print(counts)  # Counter({80: 3, 443: 2, 8080: 1})

Common methods

Method Purpose Example
Counter(iterable) Create from a list, string, or other iterable Counter([1, 2, 2, 3])
c[item] += 1 Increment count for an item c['404'] += 1
c[item] Get count, returns 0 if missing c['500'] returns 0
c.most_common(n) Return top n items by count c.most_common(3)
c.elements() Iterator over elements repeated by count list(c.elements())
c.update(iterable) Add counts from another iterable c.update([80, 80])
c.subtract(iterable) Subtract counts c.subtract(['404'])

Why it is useful for security scripts

Counting is one of the most common operations in security work: status codes, ports, file types, error messages, IP occurrences, and more. Counter removes the boilerplate of checking whether a key exists before incrementing it.

Example: count HTTP status codes

from collections import Counter

status_counts = Counter()

with open("scan_results.txt", "r") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        parts = line.split()
        if len(parts) == 2:
            status = parts[1]
            status_counts[status] += 1

for status, count in sorted(status_counts.items()):
    print(f"{status}: {count}")

Iterating over files line-by-line

When you write:

with open("file.txt", "r") as f:
    for line in f:
        print(line)

Python does not split the file into words. It yields one line at a time, including the trailing newline character \n at the end of each line. That is why you usually call .strip() to remove whitespace and the newline.

with open("file.txt", "r") as f:
    for line in f:
        line = line.strip()  # remove leading/trailing whitespace and \n
        # now line is the content without the newline

readlines() does essentially the same thing but reads the entire file into a list first. Iterating over the file object directly is preferred for large files because it is memory-efficient.