Adam Grey
Adam Grey

Reputation: 95

Not enough values to unpack in Python

I'm trying to allow users to manipulate a list in Python.

number_of_commands = int(input())
x = 0
my_list = []
while x <= number_of_commands:
    command, i, e = input().split(' ')
    command = str(command)
    i = int(i)
    e = int(e)
    x = x + 1

    if command == 'insert':
        my_list.insert(i, e)
    elif command == 'print':
        print(my_list)
    elif command == 'remove':
        my_list.remove(e)
    elif command == 'append':
        my_list.append(e)
    elif command == 'sort':
        my_list.sort()
    elif command == 'pop':
        my_list.pop()
    elif command == 'reverse':
        my_list.reverse()
    else:
        print("goodbye")

When users enter a command which requires two integers (such as insert), the program works, but when users enter something like print I get the error "not enough values to unpack". It only works if you input it as print 0 0. How could I allow users to enter commands with integers and without integers?

Upvotes: 0

Views: 2002

Answers (4)

Schonfinkel
Schonfinkel

Reputation: 809

This error occurs since you're always expecting a command to have 3 inputs:

command, i, e = input().split(' ')

This is what happens when you use just print:

>>> "print".split(' ')
['print']

So the output of input.split() is a list with only one element. However:

command, i, e = input().split(' ')

is expecting 3 elements: command, i and e.

Other answers already showed you how to solve modifying your code, but it can get pretty clunky as you add more commands. You can use Python's native REPL and create your own prompt. (Original post where I read about the cmd module)

from cmd import Cmd

class MyPrompt(Cmd):
    my_list = []

    def do_insert(self, *args):
        """Inserts element in List"""
        self.my_list.append(*args)

    def do_print(self, *args):
        print(self.my_list)

    def do_quit(self, args):
        """Quits the program."""
        raise SystemExit


if __name__ == '__main__':
    prompt = MyPrompt()
    prompt.prompt = '> '
    prompt.cmdloop('Starting prompt...')

Example:

$ python main.py
Starting prompt...
> insert 2
> insert 3
> insert 4
> print
['2', '3', '4']
> 

cmd also lets you document the code, since I didn't make a docstring for print this is what gets shown once I type help in the terminal:

> help

Documented commands (type help <topic>):
========================================
help  insert  quit

Undocumented commands:
======================
print

I leave adding the other commands and an fun exercise to you. :)

Upvotes: 0

Lo&#239;c
Lo&#239;c

Reputation: 11943

def my_function(command='print', i=0, e=0):
    # your function code here

user_input = input().split(' ')
if len(user_input) > 3:
    print('usage : function i e')
else:
    my_function(*user_input)

Using * before the list converts the list as arguments for your function.

Using a function is a nice way to have default values in case they aren't defined.

Upvotes: 1

aclown
aclown

Reputation: 101

You can use

command, *values = input().split(' ')

values is a list. For example the 'insert' part becomes:

if command == 'insert':
    my_list.insert(int(values[0]), int(values[1]))

Upvotes: 4

M. Mansour
M. Mansour

Reputation: 566

Here is where the unpacking is happening:

command, i, e = input().split(' ')

entering "print" only won't allow this line to execute properly, as no values for i and e were provided.

So just read the input, then split it and check how many arguments did the user supply:

input_str = input()
input_str_split = input_str.split(' ')
if len(input_str_split) == 3:
    command, i, e = input_str_split
    i = int(i)
    e = int(e)
else:
    command = input_str_split

Upvotes: 0

Related Questions