Search code examples
pythonpython-2.7dictionarystring-formattingargument-unpacking

python variable unpacking fails


7.10 and for some reason the following code snippet is producing an error...

device_info = {'username': 'test', 'password': 'test', 'appliance': 'name', 'hostname': 'hostname', 'prodcut': 'juice'}
print "{} {} {} {} {}".format(**device_info)

This raises an exception:

Traceback (most recent call last):
  File "python", line 4, in <module>
    print "{} {} {} {} {}".format(**device_info)
IndexError: tuple index out of range

I believe this code should be syntactically sound, however, I don't seem to be able to unpack my dict to pass to any functions, not sure why that doesn't work.


Solution

  • You are passing in your fields as keyword arguments, because you are using ** syntax:

    "....".format(**device_info)
    #             ^^
    

    Your placeholders, however, specifically only work with positional arguments; placeholders without any name or index, are automatically numbered:

    "{} {} {} {} {}".format(...)
    # ^0 ^1 ^2 ^3 ^4
    

    This is why you get an index error, there is no positional argument with index 0. Keyword arguments have no index, because they are essentially key-value pairs in a dictionary, which are unordered structures.

    If you wanted to include the values from the dictionary into a string, then you need to explicitly name your placeholders:

    "{username} {password} {appliance} {hostname} {prodcut}".format(**device_info)
    

    (but note the misspelling of product as prodcut, you may want to check if your dictionary keys are spelled correctly).

    You'd get all the values inserted in the named slots:

    >>> print "{username} {password} {appliance} {hostname} {prodcut}".format(**device_info)
    test test name hostname juice
    

    If you expected the keys to be printed, then you'd have to pass in the device_info keys as separate positional arguments; "...".format(*device_info) (single *) would do just that, but then you'd also have to content with the 'arbitrary' dictionary order that the keys would be listed in.