'Counting dictionary elements from Perl to Python

Looking for a best way to translate this piece of code from Perl to Python:

my @arr = ();
#          [  0  ,  1  ,   2   ,   3  ]
push @arr ,[$time,$host,$status,$bytes];
  my %reqs_host;
  my %bytes_host;
  my %errors_host;
  foreach(@arr){  
    $reqs_host{$_->[1]}++;
    $bytes_host{$_->[1]} += $_->[3];
    $errors_host{$_->[1]}++ if $_->[2] =~ /^[45]/;
  }

If I understand it correctly the cycle above iterates through each element in arr array and how many time host appear, how many bytes count are related to it and errors...

But I don't quite get the meaning of default variable $_, have Python background, not Perl.

UPDATE: after some brainstorming, I've come complete understanding of these Perl code but still not sure how to do it in Python, especially this piece:

$reqs_host{$_->[1]}++;


Solution 1:[1]

Not tested but should be something like this:

arr = []
arr.append((time, host, status, bytes_))
reqs_host, bytes_host, errors_host = {}, {}, {}
for item in arr:
    reqs_host[item[1]] = reqs_host.get(item[1], 0) + 1
    bytes_host[item[1]] = bytes_host.get(item[1], 0) + item[3]
    if item[2] and item[2][0] in "45": 
        errors_host[item[1]] = errors_host.get(item[1], 0) + 1

Solution 2:[2]

My Pythonizer generates this code for that input:

#!/usr/bin/env python3
# Generated by "pythonizer -mV q23173366.pl" v0.973 run by snoopyjc on Thu Apr 21 01:01:08 2022
import re, builtins, perllib

perllib.init_package("main")

_d = []
status = ""
host = ""
time = ""
bytes_ = ""

builtins.__PACKAGE__ = "main"
arr = []
#          [  0  ,  1  ,   2   ,   3  ]
arr.append([time, host, status, bytes_])
reqs_host = {}
bytes_host = {}
errors_host = {}
for _d in arr:

    reqs_host[_d[1]] = perllib.num(reqs_host.get(_d[1])) + 1
    bytes_host[_d[1]] = perllib.num(bytes_host.get(_d[1])) + perllib.num(_d[3])
    if re.search(r"^[45]", _d[2]):
        errors_host[_d[1]] = perllib.num(errors_host.get(_d[1])) + 1

Note: perllib.num does conversion from str/None to a number like perl would do (e.g. None gets mapped to 0).

Solution 3:[3]

$_ is the default variable for foreach loops in perl. Generally, it's considered better practice to define an explicit variable, as so:

foreach my $element (@list_of_stuff) { ... }

The $_->[1] is a dereferenced indexing operation. In your loop, $_ refers to a reference to an array, so $_->[1] dereferences the array, and gets element 1.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 snoopyjc
Solution 3 user3243135