Python How to create multiplle values against a single key in dictionary

[Python, datastructres] How to create multiplle values against a single key in dictionary like below

main_dict = { 'stats': IP_dict_name_1, 'Add': IP_dict_name_2}  
IP_dict_name_1 = {uniq_ip_1 : [time, threshold_counter], unique_ip_2: [time, threshold_counter]}  
IP_dict_name_1 = {uniq_ip_1 : [time, threshold_counter], unique_ip_2: [time, threshold_counter]}  

Actually I want to create a data structure in which we can log commands like the above scenario. Forexample if ‘stats’ command is already inserted to dictionary then it does not insert it again in the dictionary if not present then create the data structure above. I am confused how to do that in an efficent way. Inshort, I want to keep track of each remote_ip who executed the command and set the threshold of command i.e 5 if he wants to execute ‘stats’ command more than 3 times in a hour then it is not allowed to do so. Can anyone help to do so. Any rough idea is appreciated?

Answer

You can use pairs (command, ip) as the keys to your dictionary of logs.

In addition, I recommend the excellent dictionary method dict.setdefault.

exec_logs = {}
threshold_per_hour = 3

def exec_command(command_name, ip, current_hour):
  previous_hour, n = exec_logs.setdefault((command_name, ip), (current_hour, 0))
  if previous_hour == current_hour:
    if n >= threshold_per_hour:
      print('Command aborted: User {} cannot execute command {} more than {} times per hour.'.format(ip, command_name, threshold_per_hour))
      return # do not execute command
    else:
      exec_logs[(command_name, ip)] = (current_hour, n+1)
      print('Command {} successfully executed.'.format(command_name))
  else:
    exec_logs[(command_name, ip)] = (current_hour, 1)
    print('Command {} successfully executed.'.format(command_name))

Testing:

>>> exec_command('make coffee', 127, '1pm')
Command make coffee successfully executed.
>>> exec_command('make coffee', 127, '1pm')
Command make coffee successfully executed.
>>> exec_command('make coffee', 127, '1pm')
Command make coffee successfully executed.
>>> exec_command('make coffee', 127, '1pm')
Command aborted: User 127 cannot execute command make coffee more than 3 times per hour.
>>> exec_logs
{('make coffee', 127): ('1pm', 3)}
>>> exec_command('make coffee', 127, '2pm')
Command make coffee successfully executed.
>>> exec_logs
{('make coffee', 127): ('2pm', 1)}
>>> exec_command('make coffee', 139, '2pm')
Command make coffee successfully executed.
>>> exec_command('make coffee', 139, '2pm')
Command make coffee successfully executed.
>>> exec_command('make coffee', 139, '2pm')
Command make coffee successfully executed.
>>> exec_logs
{('make coffee', 127): ('2pm', 1), ('make coffee', 139): ('2pm', 3)}