Я использую NOT IN для сравнения и идентификатора объекта со списком идентификаторов. Сравнение, похоже, всегда оценивается как TRUE

#python #arraylist #comparison

#python #arraylist #сравнение

Вопрос:

Рассмотрим следующий код на Python 3.8:

 def clean_data(data) -> list:
    """Takes a list of Webelements and extracts needed information using RegEx.
        Groups Information into Dictionarys.
        Returns List of Dictionarys"""
    clean_data = []

    for element in data:

        datapoint = {}
        text = element.text

        name = re.search(r"A.*", text).group()

        auction_id = re.search(r"(?:LOT ID: )(d )", text).group(1)

        auction_price = re.search(r"(?:€)(d .d .d )", text).group(1)
        auction_price = auction_price.replace(",", "")
        auction_price = float(auction_price)

        date = re.search(r"(?:Sold on |Reserve not met )(.*)", text).group(1)
        date = datetime.strptime(date, "%d/%m/%Y")

        datapoint["auction_id"] = int(auction_id)
        datapoint["name"] = name
        datapoint["auction_price"] = auction_price
        datapoint["date"] = date

        clean_data.append(datapoint)
        
    return clean_data

def read_id_from_database() -> list:
    """Connects to the MySQL Database and returns a list of all existing auction_ids."""
    connection = mysql.connector.connect(**database_credentials)
    cursor = connection.cursor()
    SQL = """SELECT auction_id FROM database"""
    cursor.execute(SQL)
    ids = cursor.fetchall()
    existing_ids = [id[0] for id in ids]

    return existing_ids


def select_new_datapoints(data : list) -> list:
    """Takes a list of dictionaries. Compares the auction_id with a list of existing auction IDs.
        Returns a list of all dictionaries with new auction IDs"""
    existing_ids = read_id_from_database()
    new_datapoints = []
    for element in data:
        if int(element["auction_id"]) not in existing_ids:
            new_datapoints.append(element)
    return new_datapoints
 

Clean_data извлекает соответствующую информацию из объекта webdriver для элементов аукциона. Каждый элемент представлен в виде словаря с именем datapoint . Каждая пара ключ-значение в этом словаре представляет собой один бит информации. Функция возвращает список словарей.

read_id_from_database просто возвращает список всех идентификаторов auction_id, которые уже хранятся в моей базе данных.

select_new_datapoints проверяет, имеет ли элемент в списке Clean_data идентификатор, который уже есть в моей базе данных, сравнивая его идентификатор со списком, предоставленным read_id_from_database . Если идентификатор еще не существует, элемент добавляется в список new_datapoint .

 for element in data:
        if int(element["auction_id"]) not in existing_ids:
            new_datapoints.append(element)
 

Эти элементы будут добавлены в мою базу данных позже.

Проблема теперь в том, что метод select_new_datapoints не работает. Он всегда сохраняет все элементы, несмотря на то, что большинство или даже все идентификаторы уже присутствуют в моей базе данных.

Я уже проверил это, распечатав идентификаторы из clean_data и existing_ids в файл csv и сравнив их визуально:

Файл CSV

Оба списка идентичны, что означает, что read_id_from_database должен возвращать пустой список new_datapoints . Однако вместо этого read_id_from_database возвращает список с 226 элементами, что означает, что здесь что-то происходит:

 new_datapoints = []
    for element in data:
        if int(element["auction_id"]) not in existing_ids:
            new_datapoints.append(element)
    return new_datapoints
 

Я предполагаю, что по какой-то причине

     if int(element["auction_id"]) not in existing_ids:
        new_datapoints.append(element)
 

всегда оценивается как TRUE, и поэтому все элементы добавляются.
Я не смог выяснить, почему это так, поскольку

 if int(element["auction_id"]) not in existing_ids:
 

Должно работать так, как задумано, и мой csv показал мне, что идентификатор каждого элемента уже есть в списке existing_ids . Я также уже проверил типы данных, которые я сравниваю, они оба являются int.

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

1. id это встроенное имя в Python, вы не должны ничего так называть. [id[0] for id in ids] из-за этого может быть проблематичным. Кроме того, использовали ли вы отладчик или операторы печати, чтобы проверить содержимое existing_ids и убедиться, что оно соответствует ожидаемому, включая ожидаемый тип? Вы проверили, что element["auction_id"] разрешается, включая тип?

2. @RandomDavis имя id не должно быть проблемой

3. Какова схема базы данных для таблицы базы данных? Возможно, вы не получаете целые числа обратно из read_id_from_database

4. @JackSmith Это действительно была проблема. Столбец идентификатора в моей базе данных был целочисленным. Однако по какой-то причине в python я получил их обратно в виде строки. Теперь я снова явно преобразовал их в целые числа в python.