Home > OS >  Split one list into two lists just by unpacking?
Split one list into two lists just by unpacking?

Time:10-22

I can split a list by slicing, but how to do it by unpacking?

What I have

When unpack, I'm getting one list and one string.

mylist=["start","next1","next2","next3","end"]


# Desired Result - two lists 
part1, part2= mylist[:-1],[mylist[-1]]
print(f"Slicing 2: {type(part1)} {part1} {type(part2)} {part2}")

# Not the desired result - one list and one string
*part1,part2 = mylist
print(f"Unpacking: {type(part1)} {part1} {type(part2)} {part2}")

Result:

Slicing: <class 'list'> ['start', 'next1', 'next2', 'next3'] <class 'list'> ['end']  
Unpacking: <class 'list'> ['start', 'next1', 'next2', 'next3'] <class 'str'> end

How to split a list into two lists just by unpacking?

CodePudding user response:

To elaborate Steven Rumbalski's comments:

Unpacking with remainder *

Unpacking with *part1,part2 = mylist will split the list into the last item part2 (which is a str) and the remaining items into part1 (remainder denoted by asterisk *). See Partial list unpack in Python.

Wrapping an item into a list

The slicing with index mylist[-1] also results in a single item of type str. But you wrapped it into a list by surrounding with brackets:

# Desired Result - two lists 
part1, part2= mylist[:-1],[mylist[-1]]  # see after the comma

This can also be done in two separate statements when unpacking:

>>> *first_items, last_item = mylist
>>> print(first_items, [last_item])  # the last item is wrapped as list
['start', 'next1', 'next2', 'next3'] ['end']

Note the [last_item] which wraps the item into a new list.

An expressive and simple way

As Steven side-noted, you can use the slicing-colon : to get new lists:

# `-1` is the index where the list is split
# `:` will take elements before or after the index into a new list
first_parts, last_parts = mylist[:-1], mylist[-1:]  # results in two lists

This way, you can easily adjust the split-position:

split_index = -1  # split before last item
first_parts, last_parts = mylist[:split_index], mylist[split_index:]  # results in two lists
print(first_parts, last_parts, sep='\n')

Result:

['start', 'next1', 'next2', 'next3']
['end']

Or even have 2 splits resulting in 3 lists:

first = 1  # split after firs item
last = -1  # split before last item
first_parts, middle_parts, last_parts = mylist[:first], mylist[first:last], mylist[last:]  # 3 lists
print(first_parts, middle_parts, last_parts, sep='\n')

Output:

['start']
['next1', 'next2', 'next3']
['end']
  • Related