Построение списка динамически с объектами - PullRequest
0 голосов
/ 11 ноября 2019

Я создаю список компонентов SP 500, чтобы сохранить его в рассоле.

Я получаю элементы по ссылке в коде, затем получаю необходимую информацию и создаю объект для каждоговещь.

Вот в чем проблема -> Затем я хочу сохранить каждый объект в списке, который я хочу повторить в будущем.

В списке хранится только последний объект цикла, а не каждый объект, как он показывается.

Это должно быть довольно легко сделать, но я просто не могу найтиответ о том, почему это происходит

def save_sp500_tickers():
    resp = requests.get(
        'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
    soup = bs.BeautifulSoup(resp.text, "lxml")
    table = soup.find('table', {'class': 'wikitable sortable'})
    components = []
    data = {}
    for row in table.findAll('tr')[1:]:

        ticker = row.findAll('td')[0].text.replace('\n', '') # AAPL
        name = row.findAll('td')[1].text.replace('\n', '') # Apple Inc
        sector = row.findAll('td')[3].text.replace('\n', '') # Information Technology
        mapping = str.maketrans(".", "-")

        ticker = ticker.translate(mapping)
        name = name.translate(mapping)
        sector = sector.translate(mapping)

        data['ticker']=ticker
        data['name']=name
        data['sector']=sector

        print(data) # {'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'}
        components.append(data) # I add each component to the list


    with open("SP500components.pickle", "wb") as f:
        pickle.dump(components, f)

    print(components) # this gives me the list with only the last item repeated 

    return components

save_sp500_tickers()

Цель состоит в том, чтобы получить список, который выглядит следующим образом:

[{'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'},
{'ticker': 'ETN', 'name': 'Eaton Corporation', 'sector': 'Industrials'},
{'ticker': 'EBAY', 'name': 'eBay Inc-', 'sector': 'Consumer Discretionary'},
{'ticker': 'ECL', 'name': 'Ecolab Inc-', 'sector': 'Materials'},
{'ticker': 'EIX', 'name': "Edison Int'l", 'sector': 'Utilities'},
...,
...]

Вместо этого я получаю список, в котором отображается только последний объект, кратныйраз, как это:

[{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
{'ticker': 'ZTS', 'name': 'Zoetis', 'sector': 'Health Care'},
...,
...]

1 Ответ

1 голос
/ 11 ноября 2019

Это все до вашего data объекта. Вы инициализируете его вне цикла for. Поскольку это словарь, он изменчив в Python, и когда вы добавляете его в список, вы просто добавляете ссылку на этот data, который диктует каждую итерацию цикла, а не новый словарь. Таким образом, в конце ссылка просто указывает на самую последнюю версию диктата, следовательно, почему она выглядит несколько раз одинаково - это один и тот же диктат.

Эта страница может помочь понять, что происходит.

Попробуйте переместить инициализацию dict внутри цикла for:

def save_sp500_tickers():
    resp = requests.get(
        'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
    soup = bs.BeautifulSoup(resp.text, "lxml")
    table = soup.find('table', {'class': 'wikitable sortable'})
    components = []
    for row in table.findAll('tr')[1:]:
        ticker = row.findAll('td')[0].text.replace('\n', '') # AAPL
        name = row.findAll('td')[1].text.replace('\n', '') # Apple Inc
        sector = row.findAll('td')[3].text.replace('\n', '') # Information Technology
        mapping = str.maketrans(".", "-")

        ticker = ticker.translate(mapping)
        name = name.translate(mapping)
        sector = sector.translate(mapping)

        data = dict(ticker=ticker, name=name, sector=sector)

        print(data) # {'ticker': 'AAPL', 'name': 'Apple Inc-', 'sector': 'Information Technology'}
        components.append(data) # I add each component to the list


    with open("SP500components.pickle", "wb") as f:
        pickle.dump(components, f)

    print(components) # this gives me the list with only the last item repeated 

    return components
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...