- Related Questions & Answers
- unpack() function in PHP
- How can we unpack a string of integers to complex numbers in Python?
- What does ** (double star) and * (star) do for parameters in Python?
- How to draw a star by using canvas HTML5?
- Explain the Star Height of Regular Expression and Regular Language
- How to match a word in python using Regular Expression?
- How to match nonword characters in Python using Regular Expression?
- How to match a whitespace in python using Regular Expression?
- How to match only digits in Python using Regular Expression?
- How to extract numbers from text using Python regular expression?
- How to extract date from text using Python regular expression?
- How to strip spaces/tabs/newlines using Python regular expression?
- How to remove tabs and newlines using Python regular expression?
- How to match a single character in python using Regular Expression?
- How to match a nonwhitespace character in python using Regular Expression?

- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who

One of the basic limitation of unpacking is that you must know the length of the sequences you are unpacking in advance.

random_numbers = [0, 1, 5, 9, 17, 12, 7, 10, 3, 2] random_numbers_descending = sorted(random_numbers, reverse=True) print(f"Output \n*** {random_numbers_descending}")

*** [17, 12, 10, 9, 7, 5, 3, 2, 1, 0]

If I now wanted to find out the largest and second largest from the numbers, we will get an exception "too many values to unpack".

print(f"Output \n*** Getting the largest and second largest") largest, second_largest = random_numbers_descending

*** Getting the largest and second largest

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) in 1 print(f"Output \n*** Getting the largest and second largest") ----> 2 largest, second_largest = random_numbers_descending ValueError: too many values to unpack (expected 2)

Python often rely on indexing and slicing. For example, when I want to extract the largest, second largest from a list of items below is how we can do.

largest = random_numbers_descending[0] print(f"Output \n*** Getting the largest - {largest}")

*** Getting the largest - 17

second_largest = random_numbers_descending[1] print(f"Output \n*** Getting the second largest - {second_largest}")

*** Getting the second largest - 12

rest_of_numbers = random_numbers_descending[2:] print(f"Output \n*** Getting the rest of numbers - {rest_of_numbers}")

*** Getting the rest of numbers - [10, 9, 7, 5, 3, 2, 1, 0]

While this works, all of the indexing and slicing is visually noisy. In practice, it is error prone to divide the members of a sequence into various subsets this way.

To do it better, Python supports catch-all unpacking through a starred expression.

This starred syntax allows one part of the unpacking assignment to receive all values that do not match any other part of the unpacking pattern.

largest,second_largest, *rest_of_numbers = random_numbers_descending print(f"Output \n largest: {largest} \n second_largest:{second_largest} \n rest_of_numbers:{rest_of_numbers}")

largest: 17 second_largest:12 rest_of_numbers:[10, 9, 7, 5, 3, 2, 1, 0]

How does the above code look? In a single line which is also easier to read we are able to acheive the output. A starred expression may appear in any position, so you can get the benefits of catch-all unpacking anytime you need to extract one slice

largest: 17 rest_of_numbers:[12, 10, 9, 7, 5, 3, 2, 1] smallest:0

*rest_of_numbers, second_smallest, smallest = random_numbers_descending print(f"Output \n rest_of_numbers:{rest_of_numbers} \n second_smallest: {second_smallest} \n smallest:{smallest}")

rest_of_numbers:[17, 12, 10, 9, 7, 5, 3, 2] second_smallest: 1 smallest:0

However, to unpack assignments that contain a starred expression, you must have at least one required part, or else you’ll get a SyntaxError. We can’t use a catch-all expression on its own.

*rest_of_numbers = random_numbers_descending

File "", line 1 *rest_of_numbers = random_numbers_descending ^ SyntaxError: starred assignment target must be in a list or tuple

We also cannot use multiple catch-all expressions in a single-level unpacking pattern. This is another important note to consider.

*rest_of_numbers, *more_smallest, smallest = random_numbers_descending

File "", line 1 *rest_of_numbers, *more_smallest, smallest = random_numbers_descending ^ SyntaxError: two starred expressions in assignment

But it is possible to use multiple starred expressions in an unpacking assignment statement, as long as they’re catch-alls for different parts of the multilevel structure being unpacked.

player_grandslame_and_atptitles = { 'Federer': (20, 103), 'Nadal': (20,84),} ((player1, (grandslam1, *atptitles1)), (player2, (grandslam2, *atptitles2))) = player_grandslame_and_atptitles.items() print(f'Output \nPlayer - {player1} Have acheived {grandslam1} grandslams and , {atptitles1} atp tour titles') print(f'Player - {player2} Have acheived {grandslam2} grandslams and , {atptitles2} atp tour titles')

Player - Federer Have acheived 20 grandslams and , [103] atp tour titles Player - Nadal Have acheived 20 grandslams and , [84] atp tour titles

Starred expressions become list instances in all cases. If there are no leftover items from the sequence being unpacked, the catch-all part will be an empty list. This is especially useful when you are processing a sequence that you know in advance has at least N elements.

random_numbers = [0, 1] first, second, *rest = random_numbers print(f"Output \n{first, second, rest}")

(0, 1, [])

Advertisements