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']