Пропустить строку в CSV, если содержит строки из списка

#python #python-2.7 #loops #csv

#Python #Python-2.7 #циклы #csv

Вопрос:

У меня есть список из примерно 500 строк, которые я хочу сверить с файлом CSV, содержащим 25 000 строк. То, что у меня сейчас есть, похоже, застревает в цикле. Я в основном хочу пропустить строку, если она содержит какую-либо из строк в моем списке строк, а затем извлечь другие данные.

 stringList = [] #strings look like "AAA", "AAB", "AAC", etc.

with open('BadStrings.csv', 'r')as csvfile:
    filereader = csv.reader(csvfile, delimiter=',')
    for row in filereader:
        stringToExclude = row[0]
        stringList.append(stringToExclude)

with open('OtherData.csv', 'r')as csvfile:
    filereader = csv.reader(csvfile, delimiter=',')
    next(filereader, None) #Skip header row
    for row in filereader:
        for s in stringList:
            if s not in row:
                data1 = row[1]
  

Редактировать: не бесконечный цикл, но цикл занимает слишком много времени.

Комментарии:

1. Я не понимаю, как вы попадаете в бесконечный цикл. Я действительно вижу проблему с перезаписью data1 каждый раз, когда s не находится в строке. Вероятно, это будет происходить часто для каждой строки, так как вы проверяете каждый s в StringList отдельно. Я бы перестроил ваш второй цикл for и оператор if. Возможно, используйте оператор continue .

2. @NielsHenkens Я предположил, что это бесконечный цикл после пары тестовых запусков, которые не завершаются даже через 30 минут. Не думаю, что это должно быть так long…is есть какой-нибудь способ ускорить цикл?

3. Я так понимаю, что строка или строка [0] — это не просто строка s, но может содержать s? В противном случае вы могли бы изменить оператор if на что-то вроде ‘if строка [x] в StringList:’. Это значительно ускорило бы процесс. Одна вещь, которую нужно оптимизировать, это то, что ваше «если не в строке:» неверно, не оптимально. Прямо сейчас, если одна из строк StringList находится в строке, то data1 все равно получит обновление 499 раз. Я не думаю, что это ваше желаемое поведение.

4. @NielsHenkens Да. Строка — это не просто строка s, она содержит s.

Ответ №1:

по словам Нильса, я бы изменил цикл 2 и перебрал саму строку и проверил, находится ли текущая запись строки внутри «плохого» списка:

 for row in filereader:
    for s in row:
       if s not in stringlist:
           data1 = row[0]
  

И я также не знаю, что вы хотите сделать с data1, но вы всегда меняете ссылку на объект, когда элемента нет в StringList.
Вы можете использовать список для добавления элементов в список с data1.append(item)

Комментарии:

1. Ваш ответ не то, что я имел в виду. Не зная, как именно выглядит строка, но это решение работает только в том случае, если элемент строки является именно тем значением, которое вы хотите проверить в StringList (а не более длинной строкой, содержащей часть нежелательной подстроки из StringList). И вы также перебираете все элементы в строке и все еще обновляете data1 для каждого элемента строки, которого нет в StringList.

Ответ №2:

Вы могли бы попробовать что-то вроде этого.

 stringList = [] #strings look like "AAA", "AAB", "AAC", etc.

with open('BadStrings.csv', 'r')as csvfile:
    filereader = csv.reader(csvfile, delimiter=',')
    for row in filereader:
        stringToExclude = row[0]
        stringList.append(stringToExclude)

data1 = [] # Right now you are overwriting your data1 every time. I don't know what you want to do with it, but you could for exmaple add all row[1] to a list data1
with open('OtherData.csv', 'r')as csvfile:
    filereader = csv.reader(csvfile, delimiter=',')
    next(filereader, None) #Skip header row
    for row in filereader:
        found_s = False
        for s in stringList:
            if s in row:
                found_s = True
                break
        if not found_s:
            data1.append(row[1]) # Add row[1] to the list is no element of stringList is found in row. 
  

Все еще, вероятно, не значительное улучшение производительности, но, по крайней мере, цикл for for s in stringList: теперь остановится после того, как s будет найден.