1
\$\begingroup\$

I am solving the following HackerRank problem:

Consider a list (list = []). You can perform the following commands:

  • insert i e: Insert integer e at position i.
  • print: Print the list.
  • remove e: Delete the first occurrence of integer e.
  • append e: Insert integer e at the end of the list.
  • sort: Sort the list.
  • pop: Pop the last element from the list.
  • reverse: Reverse the list.

Initialize your list and read in the value of followed by lines of commands where each command will be of the types listed above. Iterate through each command in order and perform the corresponding operation on your list.

My solution was:

if __name__ == '__main__':
    N = int(input())
    
    my_list = []
    
    commands = dict(
            insert=lambda i,v: my_list.insert(i,v),
            print=lambda: print(my_list),
            remove=lambda e: my_list.remove(e),
            append=lambda v: my_list.append(v),
            sort=lambda: my_list.sort(),
            pop=lambda: my_list.pop(),
            reverse=lambda: my_list.reverse()
        )
    
    for _ in range(N):
        command, *args = input().split()
        commands[command](*list(map(int, args)))
 

I did find another solution (I didn't write it) that seems cleaner than mine:

n = input()
l = []
for _ in range(n):
    s = raw_input().split()
    cmd = s[0]
    args = s[1:]
    if cmd !="print":
        cmd += "("+ ",".join(args) +")"
        eval("l."+cmd)
    else:
        print l
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Suggestions:

  • Most of your lambdas are unnecessary wrappers around perfectly fine functions, so I'd just use the latter instead.
  • The list in (*list(map(...))) is unnecessary, just unpack the iterable that map gets you.
  • There's nothing else in your code, so importing it doesn't give you anything, so you'd just run the script, so if __name__ == '__main__': is rather pointless.
  • I'd read the number of commands only when I need it, not early.
  • I find my_list unnecessarily verbose, a commonly used name is lst.
  • Indent the dict arguments by the standard four spaces instead of eight. So, rewritten:
lst = []

commands = dict(
    insert=lst.insert,
    print=lambda: print(lst),
    remove=lst.remove,
    append=lst.append,
    sort=lst.sort,
    pop=lst.pop,
    reverse=lst.reverse
)

for _ in range(int(input())):
    command, *args = input().split()
    commands[command](*map(int, args))

As shown in some other solutions in the discussion, we can use getattr instead of building our own dict serving pretty much the same purpose. I didn't see anyone using its default parameter, though, which can neatly cover the print command:

lst = []
for _ in range(int(input())):
    command, *args = input().split()
    getattr(lst, command, lambda: print(lst))(*map(int, args))
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the answer! About the if ... __main __ it was just copy paste from hackerrank. \$\endgroup\$
    – Nestor
    Nov 30, 2020 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.