2

I have an array that needs certain elements removed. I am trying to have list comprehension do this for me, but it is not working.

It is a two dimensional array. For each row in the array if the first item, a str, meets two qualifications I would like it to be removed. However, when I use an "and" statement it only looks at the first statement. Why is this and how do you correct it?

act_array = [row for row in act_array if row[0][-4:] != '0660' and row[0][0] != '4' ] 

So I this example I want to copy all items that do not start with a 4 and whose last 4 chars do not equal 0660

Thanks

1
  • What makes you think "it only looks at the first statement"? Can you provide example data showing the problem? Commented Apr 24, 2014 at 18:14

2 Answers 2

5

... if the first item, a str, meets two qualifications I would like it to be removed...

So, you want all of the rows which end with 0660, and all of the rows that start with 4, but none of the rows that have both.

You have a logic bug, your condition

if row[0][-4:] != '0660' and row[0][0] != '4' ] # ^ ^^^ ^ 

is logically equivalent, by deMorgan's law, to :

if not (row[0][-4:] == '0660' or row[0][0] == '4') ] # ^^^ ^^ ^^ ^^ 

(note, the negation is distributed and the and's and or's are swapped. That means you filter the elements which satisfy either condition. Fix it with one of:

if row[0][-4:] != '0660' or row[0][0] != '4' ] # ^ ^^ ^ 

or

if not (row[0][-4:] == '0660' and row[0][0] == '4') ] # ^^^ ^^ ^^^ ^^ 
Sign up to request clarification or add additional context in comments.

Comments

1

Seems to work as expected:

In [6]: act_array=[['4X0660'], ['4X1111'], ['1X0660'], ['1X1111']] In [7]: [row for row in act_array if row[0][-4:] != '0660' and row[0][0] != '4' ] Out[7]: [['1X1111']] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.