How to optimize code to remove n position in all lists from a list of lists

I searched the site for this problem and I found many posts about removing certain values ​​from a list of lists.

However, this does not answer my question.

Allows:

mylist=[[1,2,3,4],[100,374,283,738]]

      

Now, in my opinion, the two lists are linked. List 1 is the number of items: 1, 2, 3, 4, ... and list 2 is a feature of these items (for example, prices: $ 100, $ 374, etc.).

Now I want to remove items (number and price) from a list if list2 is a hihger of a certain value (for example, if an item is too expensive, more than $ 300)

I am trying and I got this:

n=0 # counter for position in the list
for i in mylist[1]:
    if i>300:
        for j in mylist:
            del j[n]
    n=n+1

      

result:

[[1,3],[100,283]]

      

It really works. It doesn't look very efficient: I need to access the list multiple times and I need to create new variables. Too many loops.

Since lists can use comprehension lists, I was wondering if there is a more efficient and elegant method to get the same result.

thank

+3


source to share


4 answers


Use zip

with a filter generator expression:

>>> mylist = [[1,2,3,4], [100,374,283,738]]
>>> mylist[:] = list(map(list, zip(*((a,b) for a,b in zip(*mylist) if b<300))))
>>> mylist
[[1, 3], [100, 283]]

      



Note that this preserves the old pointer mylist

to emulate how your code modifies the original list.

+3


source


It looks like you are trying to match items from mylist [0] to items from mylist [1]. If so, I would suggest using a dictionary. Moving your data into one, your script might look like:

mydict = { 1: 100, 2: 374, 3: 283, 4: 738 }

mykeys = list(mydict.keys())
for key in mykeys():
    if dict[key] > 300:
        del dict[key]

      

This is a little verbose and we have to copy the keys to the list because we cannot modify the dictionary by iterating over its keys. However, there is a short, one-line type alternative that you may be looking for.



Comprehension can also be used with dictionaries. For this example, it would look like this:

mydict = { k: mydict[k] for k in mydict.keys() if mydict[k] <= 300 }

      

Edit: There were some syntax issues in my original answer, but the corrected passages should work.

+2


source


Given that you are only trying to check the price, let go and just do a simple loop:

mylist=[[1,2,3,4],[100,374,283,738]]
print [item for item in zip(*mylist) if item[1] <= 300]

      

+1


source


If numpy

available to you, you can try the following code:

>>> import numpy as np
>>> mylist=[[1,2,3,4],[100,374,283,738]]
>>> arr = np.array(mylist)
>>> price = np.array(mylist[1])
>>> np.delete(arr, np.where(price>=300), 1).tolist()
[[1, 3], [100, 283]]

      

+1


source







All Articles