0

I have a multidimensional list with a layout like this

['Company Name', ['companyemail@email.com']]
['Company Name', ['companyemail@email.com','companyemail@email.com']]
['Company Name', ['companyemail@email.com']]

There are about 500 of these lines in the list. However due to the inefficiencies of the corporate world, some vendors haven provide credible contact info and this is the result:

['Company Name', ['companyemail@email.com']]
['Company Name', ['companyemail@email.com','companyemail@email.com']]
['Company Name', []]
['Company Name', []]

I have created a for loop which checks if the second element in the list a certain spot is empty, however it seems like 80% through the list it stops removing elements that are supposed to be removed.

I think I know why its doing this, and its because how my for loop is:

count=0
  for k in (list1):
    if not list1[count][1]:
      list1.pop(count)
    else:
      count+=1

It used to be:

count=0
  for k in (list1):
    if not list1[count][1]:
      list1.pop(count)
    count+=1

but i had to change it because i noticed if there were items in the list that needed to be removed and they were right next to each other the second would be skipped because the count variable would add 1 while the location of the item would go back one.

rmcknst2
  • 195
  • 1
  • 2
  • 11

3 Answers3

2

Instead of your for loops you could use the python filter.

list(filter(lambda x: x[1]!=[],list1))

With this filter you iterate through all elements in the list and check if the second element is not equal to the empty list. If this is true you keep it, otherwise you drop it. Then you create a new list with just this elements.

Syrius
  • 941
  • 6
  • 22
  • it gives me this error when i tried to implement it: list2=list(filter(lambda x: x[1]!=[],list1)) TypeError: 'list' object is not callable @Syrius – rmcknst2 Jun 11 '19 at 20:17
  • I imagined your list to look something like this: list1 = [['Company Name', ['companyemail@email.com']], ['Company Name', ['companyemail@email.com','companyemail@email.com']], ['Company Name', []], ['Company Name', []]] Is this not the case? – Syrius Jun 11 '19 at 20:21
  • Is by any chance your list called list? Then you get the error that you get. If so you need to change the name of your list as "list" is actually a reserved word in python. If your variable has that name you overwrite the link to the list datastructure and thus get that error. – Syrius Jun 11 '19 at 20:23
  • yeah, that is how it's set up. My list is called list1 – rmcknst2 Jun 11 '19 at 20:24
  • Could it be that you used the term list for any other variable? Because if you have the same structure it should actually work on python2 and python3. I just tested it on my machine – Syrius Jun 11 '19 at 20:29
1

Syrius' answer is a great one-liner. If you want to know why you had a problem with your code, you were looping through the list and modifying it at the same time. To prevent that, you can loop through the list backwards. Here I also used range to provide the index instead of the count variable.

for k in range(len(list1) -1, 0, -1):
    if not list1[k][1]:
        list1.pop(k)

It's still modifying list1 as you go, but the modifications do not not affect the operations that occur on successive iterations.

Deepstop
  • 3,627
  • 2
  • 8
  • 21
  • Thank you. I didn't even think about starting from the end on working my way upwards. Is this a common solutin? – rmcknst2 Jun 11 '19 at 20:20
  • Could you explain the syntax for this part and what it means? (len(list1) -1, 0, -1): I get the len( part of it but the 3 numbers at the end confuse me – rmcknst2 Jun 11 '19 at 20:26
  • @rmcknst2 The range functions arguments are: start, stop and step. Start is where you start counting from. If the list was 10 elements then you would start at 9, because the indices are 0 to 9. So that's 1 less than the length of the list. You stop counting at 0, which is the index of the first element, and you step through the list -1 at a time, so the range returns an iterator (9, 8, 7, 6, 5, 4, ,3, 2, 1, 0). – Deepstop Jun 11 '19 at 20:52
1

Using indexes to delete is much slower than using a list comprehension. You should do it in a more "Pythonic" way:

list1 = [ company for company in list1 if company[1] ] 
Alain T.
  • 40,517
  • 4
  • 31
  • 51