2

I have a webscraper to download all the stocks from TradingView.com that meet a certain criteria, then stores the names of these stocks in a list. I then have a script to save the names of the stocks along with the date they were added, into a CSV file.

My question is why do I need to loop through a list multiple times to remove the irrelevant data? I've tried using two lists to avoid editing a list you are currently looping through.

Here's the code :

# Removes irrelevant, old stocks
for i in range(5):
    to_be_added = old_stocks
    for stock in old_stocks:
        if stock[0] not in new_stocks:
            print(f"Removed irrelevant stock : {stock}")
            del to_be_added[old_stocks.index(stock)]

If I remove the for i in range at the top, It only removes two irrelevant stocks.

to_be_added and old_stocks are both the same list, I use them to avoid editing a list I'm currently looping through as stated above. new_stocks is a list of stock names from the webscraper. old_stocks is a list (imported CSV file) containing nested lists containing the stock names and dates added to the file.

# An example of new_stocks
['NASDAQ:CMBG', 'NASDAQ:GLG', 'NASDAQ:KTCC']

# An example of old_stocks
[['NASDAQ:CBMG', 'November 07, 2020'], ['NASDAQ:GLG', 'November 08, 2020'], ['NASDAQ:KTCC', 'November 08, 2020'], ['NASDAQ:ATHE', 'November 08, 2020']] 
martineau
  • 119,623
  • 25
  • 170
  • 301

2 Answers2

3

Iterators over lists are just wrappers over looping with the index, and deleting an element shifts the entire list. Let's say you have the list [1, 2, 3], and you start iterating over it:

[1, 2, 3]
 ^ iterator here

Then, you delete the element and the iterator advances to slot 2:

[2, 3]
    ^ iterator here, 2 got skipped

If you meant for to_be_added to be a copy of old_stocks, then you have to use to_be_added = old_stocks.copy(). Since python copies by reference. Alternatively, just use list comprehension filtering:

to_be_added = [stock for stock in old_stocks if stock[0] not in new_stocks]
Aplet123
  • 33,825
  • 1
  • 29
  • 55
0

Make a copy since del to_be_added removed it from old_stocks

for i in range(5):
    to_be_added = old_stocks.copy()
    for stock in old_stocks:
        if stock[0] not in new_stocks:
            print(f"Removed irrelevant stock : {stock}")
            del to_be_added[old_stocks.index(stock)]
            

Your requirements are not very clear. You can used list comprehension to achieve your goal in pythonic way

Aaj Kaal
  • 1,205
  • 1
  • 9
  • 8