简体   繁体   中英

One liner for poping list of lists based on condition

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.

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)

This would be a good use-case for filter() .

eg,

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM