I've got the following lists:
leftoverbricks = [['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0'], ['purple3', 'z2', 'x8', 'z2', 'x0']]
and
startingbrick = ['purple3', 'z2', 1, 1]
I'd like to pop an element from leftoverbricks where startingbrick[0]
matches first element of list of list from leftoverbricks, so leftoverbricks[][0]
I've created a function that works:
def removebrick(tempbrick, templist):
reducedlist = templist
for tempelement in reducedlist:
if tempelement[0] == tempbrick[0]:
reducedlist.pop(reducedlist.index(tempelement))
return reducedlist
and which gives the correct result of:
reducedleftoverbricks = removebrick(startingbrick, leftoverbricks)
reducedleftoverbricks = [['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0']]
But it's not elegant. I hope such thing can be done with one liner and by mutating original leftoverbricks
list rather than creating a new list variable reducedleftoverbricks
. I did a few attempts at one liner list comprehension but so far failed.
CodePudding user response:
You can use a list comprehension to remove the elements from leftoverbricks
that match the first element of startingbrick
.
Example:
leftoverbricks = [['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0'], ['purple3', 'z2', 'x8', 'z2', 'x0']]
startingbrick = ['purple3', 'z2', 1, 1]
leftoverbricks = [brick for brick in leftoverbricks if brick[0] != startingbrick[0]]
print(leftoverbricks)
This will modify leftoverbricks
in place, so you don't need to create a new list variable.
Otuput:
[['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0']]
CodePudding user response:
Personally, I'd consider using a filter. Note that the filter is going to be lazily evaluated, so you can evaluate the whole filter in the spot where you'd like the reduced list.
for brick in filter(lambda n: n[0] != startingbrick[0], leftoverbricks):
do_more_work(brick)
CodePudding user response:
This would be a good use-case for filter().
e.g.,
leftoverbricks = [['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0'], ['purple3', 'z2', 'x8', 'z2', 'x0']]
startingbrick = ['purple3', 'z2', 1, 1]
def removebrick(tempbrick, templist):
key, *_ = templist
return list(filter(lambda v: v[0] != key, tempbrick))
print(removebrick(leftoverbricks, startingbrick))
Output:
[['purple1', 'y8', 'x0', 'y8', 'x1'], ['purple2', 'y6', 'y0', 'x8', 'y0']]
Note:
This does not modify the input list (leftoverbricks). If you want it to be destructive then just assign the return value from this function to the appropriate variable