Can you pass a list to a function in python?

This chapter is from the book

5.7 Passing Lists to Functions

In the last chapter, we mentioned that all objects are passed by reference and demonstrated passing an immutable object as a function argument. Here, we discuss references further by examining what happens when a program passes a mutable list object to a function.

Passing an Entire List to a Function

Consider the function modify_elements, which receives a reference to a list and multiplies each of the list’s element values by 2:

In [1]: def modify_elements(items):
   ...:     """"Multiplies   all element values in items by 2."""
   ...:     for i in range(len(items)):
   ...:         items[i] *= 2
   ...:

In [2]: numbers = [10, 3, 7, 1, 9]

In [3]: modify_elements(numbers)

In [4]: numbers
Out[4]: [20, 6, 14, 2, 18]

Function modify_elements’ items parameter receives a reference to the original list, so the statement in the loop’s suite modifies each element in the original list object.

Passing a Tuple to a Function

When you pass a tuple to a function, attempting to modify the tuple’s immutable elements results in a TypeError:

In [5]: numbers_tuple = (10, 20, 30)

In [6]: numbers_tuple
Out[6]: (10, 20, 30)

In [7]: modify_elements(numbers_tuple)
-------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
----> 1 modify_elements(numbers_tuple)

 in   modify_elements(items)
      2     """"Multiplies   all element values in items by 2."""
      3     for i in range(len(items)):
----> 4         items[i] *= 2
      5
      6

TypeError: 'tuple' object   does not support item assignment

Recall that tuples may contain mutable objects, such as lists. Those objects still can be modified when a tuple is passed to a function.

A Note Regarding Tracebacks

The previous traceback shows the two snippets that led to the TypeError. The first is snippet [7]’s function call. The second is snippet [1]’s function definition. Line numbers precede each snippet’s code. We’ve demonstrated mostly single-line snippets. When an exception occurs in such a snippet, it’s always preceded by ----> 1, indicating that line 1 (the snippet’s only line) caused the exception. Multiline snippets like the definition of modify_elements show consecutive line numbers starting at 1. The notation ----> 4 above indicates that the exception occurred in line 4 of modify_elements. No matter how long the traceback is, the last line of code with ----> caused the exception.

You can pass a list as an argument of Python function the same way as any other type and it will be the same type inside the function.

Take a look at the following example:

my_list = [1, 2, 3]

def my_func(list_as_argument):
	for elem in list_as_argument:
		print(elem)

my_func(my_list)
print(my_list)

There is a list of three numbers. You can pass this list as an argument and display all its elements one by one:

1
2
3
[1, 2, 3]

If you print a list after the function execution, it will print the same numbers.

Because lists are mutable, when you pass a list as an argument, you create a reference to this list and not a copy.

my_list = [1, 2, 3]

def my_func(list_as_argument):
	list_as_argument[0] = 8
	print(list_as_argument)

print(my_list)
my_func(my_list)
print(my_list)

If you print the list it will display numbers: 1, 2, 3.

After you modify this list, the modification will apply to the list outside the function because it was a reference and not a copy.

[1, 2, 3]
[8, 2, 3]
[8, 2, 3]

Creating a copy of a list

If you want to modify the list as a copy of the one inside parameter, you can use the copy function.

my_list = [1, 2, 3]

def my_func(list_as_argument):
	new_list = list_as_argument.copy()
	new_list[0] = 8
	print(new_list)

print(my_list)
my_func(my_list)
print(my_list)

Now, if you run the code, the modification inside the function doesn’t apply to the my_list list, because the function operates on a copy and not on the original object.

[1, 2, 3]
[8, 2, 3]
[1, 2, 3]

In Python, you can unpack list, tuple, dict (dictionary) and pass its elements to function as arguments by adding * to list or tuple and ** to dictionary when calling function.

This article describes the following contents.

  • Unpack list and tuple with *
    • With default arguments
    • With variable-length arguments
  • Unpack dict (dictionary) with **
    • With default arguments
    • With variable-length arguments

Note that if list, tuple, or dict is specified as an argument without * or **, it is not be unpacked and passed to the function as is.

See the following articles for basic usage of functions in Python, default arguments, and variable-length arguments with * and ** when defining functions.

  • Define and call functions in Python (def, return)
  • Default arguments in Python
  • Variable-length arguments (args, *kwargs) in Python

Unpack list and tuple with *

When specifying a list or tuple with * as an argument, it is unpacked, and each element is passed to each argument.

def func(arg1, arg2, arg3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

l = ['one', 'two', 'three']

func(*l)
# arg1 = one
# arg2 = two
# arg3 = three

func(*['one', 'two', 'three'])
# arg1 = one
# arg2 = two
# arg3 = three

t = ('one', 'two', 'three')

func(*t)
# arg1 = one
# arg2 = two
# arg3 = three

func(*('one', 'two', 'three'))
# arg1 = one
# arg2 = two
# arg3 = three

Lists are used in the following sample code, but the same applies to tuples.

If the number of elements does not match the number of arguments, TypeError raises.

# func(*['one', 'two'])
# TypeError: func() missing 1 required positional argument: 'arg3'

# func(*['one', 'two', 'three', 'four'])
# TypeError: func() takes 3 positional arguments but 4 were given

With default arguments

If the function has default arguments, the default arguments are used if the number of elements is insufficient. If there are many elements, TypeError raises.

def func_default(arg1=1, arg2=2, arg3=3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

func_default(*['one', 'two'])
# arg1 = one
# arg2 = two
# arg3 = 3

func_default(*['one'])
# arg1 = one
# arg2 = 2
# arg3 = 3

# func_default(*['one', 'two', 'three', 'four'])
# TypeError: func_default() takes from 0 to 3 positional arguments but 4 were given

With variable-length arguments

If the function has a variable-length argument (*args), all elements after the positional argument are passed to the variable-length argument.

def func_args(arg1, *args):
    print('arg1 =', arg1)
    print('args =', args)

func_args(*['one', 'two'])
# arg1 = one
# args = ('two',)

func_args(*['one', 'two', 'three'])
# arg1 = one
# args = ('two', 'three')

func_args(*['one', 'two', 'three', 'four'])
# arg1 = one
# args = ('two', 'three', 'four')

Unpack dict (dictionary) with **

By adding ** to dict (dictionary) and specifying it as an argument, its keys and values are treated as names and values of arguments. Each element is passed as keyword arguments.

def func(arg1, arg2, arg3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

d = {'arg1': 'one', 'arg2': 'two', 'arg3': 'three'}

func(**d)
# arg1 = one
# arg2 = two
# arg3 = three

func(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three'})
# arg1 = one
# arg2 = two
# arg3 = three

If there are not enough keys or keys that do not match the argument names, TypeError raises.

# func(**{'arg1': 'one', 'arg2': 'two'})
# TypeError: func() missing 1 required positional argument: 'arg3'

# func(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three', 'arg4': 'four'})
# TypeError: func() got an unexpected keyword argument 'arg4'

With default arguments

If the function has default arguments, only the value of the argument name matching the dictionary key is updated.

If a key does not match the argument name, TypeError is raised.

def func_default(arg1=1, arg2=2, arg3=3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

func_default(**{'arg1': 'one'})
# arg1 = one
# arg2 = 2
# arg3 = 3

func_default(**{'arg2': 'two', 'arg3': 'three'})
# arg1 = 1
# arg2 = two
# arg3 = three

# func_default(**{'arg1': 'one', 'arg4': 'four'})
# TypeError: func_default() got an unexpected keyword argument 'arg4'

With variable-length arguments

If the function has a variable-length argument (**kwargs), all elements with keys that do not match the argument name are passed to the variable-length argument.

def func_kwargs(arg1, **kwargs):
    print('arg1 =', arg1)
    print('kwargs =', kwargs)

func_kwargs(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three'})
# arg1 = one
# kwargs = {'arg2': 'two', 'arg3': 'three'}

func_kwargs(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three', 'arg4': 'four'})
# arg1 = one
# kwargs = {'arg2': 'two', 'arg3': 'three', 'arg4': 'four'}

func_kwargs(**{'arg1': 'one', 'arg3': 'three'})
# arg1 = one
# kwargs = {'arg3': 'three'}

How do you add a list to a function in Python?

How to add Elements to a List in Python.
append() : append the element to the end of the list..
insert() : inserts the element before the given index..
extend() : extends the list by appending elements from the iterable..
List Concatenation: We can use the + operator to concatenate multiple lists and create a new list..

Can you pass a list as a parameter?

You should always avoid using List as a parameter. Not only because this pattern reduces the opportunities of the caller to store the data in a different kind of collection, but also the caller has to convert the data into a List first.

How do you pass a number and a list as an argument in Python?

Use the * Operator in Python The * operator can unpack the given list into separate elements that can later be tackled as individual variables and passed as an argument to the function.