Skip to main content
 首页 » 编程设计

python之在通过多线程进程运行时保持字典的完整性

2025年04月02日29kuangbin

我通过使用多线程函数加快了进程,但是我需要保持输出和输入之间的关系。

import requests 
import pprint 
import threading 
 
ticker = ['aapl', 'googl', 'nvda'] 
url_array = [] 
 
for i in ticker: 
    url = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/' + i + '?formatted=true&crumb=8ldhetOu7RJ&lang=en-US&region=US&modules=defaultKeyStatistics%2CfinancialData%2CcalendarEvents&corsDomain=finance.yahoo.com' 
    url_array.append(url) 
 
 
def fetch_ev(url): 
    urlHandler = requests.get(url) 
    data = urlHandler.json() 
    ev_single = data['quoteSummary']['result'][0]['defaultKeyStatistics']['enterpriseValue']['raw'] 
    ev_array.append(ev_single)  # makes array of enterprise values 
 
threads = [threading.Thread(target=fetch_ev, args=(url,)) for url in 
           url_array]  # calls multi thread that pulls enterprise value 
 
 
for thread in threads: 
    thread.start() 
for thread in threads: 
    thread.join() 
 
pprint.pprint(dict(zip(ticker, ev_array))) 

代码示例输出:

1) {'aapl': '30.34B', 'googl': '484.66B', 'nvda': '602.66B'}

2) {'aapl': '484.66B', 'googl': '30.34B', 'nvda': '602.66B'}

我需要将值与正确的股票代码相匹配。

编辑:我知道字典不保留顺序。抱歉,也许我的问题有点(非常)不清楚。我有一组股票代码,与我的 url 输入的顺序相匹配。运行 fetch_ev 后,我想将这些股票代码与匹配的企业值或 ev_single 结合起来。它们的存储顺序无关紧要,但是配对(k v 对)或哪些值与哪些代码一起存储非常重要的。

Edit2 (MCVE) 我将代码更改为我所拥有的更简单的版本——这样可以更好地显示问题。抱歉,它比我想要的复杂一点。

请您参考如下方法:

为了便于维护输入和输出之间的对应关系,可以预先分配 ev_array,使其与 ticker 数组大小相同,而 fetch_ev() 线程函数可以被赋予一个额外的参数,指定该数组中用于存储获取的值的位置的索引。

为了保持 ev_array 的完整性,添加了一个 threading.RLock 以防止并发访问共享资源,否则可能会被多个人同时写入线。 (由于现在通过传递给 fetch_ev() 的索引直接引用其内容,因此这可能不是绝对必要的。)

我不知道正确的代码 ↔ 企业值(value)一致性能够验证这样做产生的结果:

{'aapl': 602658308096L, 'googl': 484659986432L, 'nvda': 30338199552L} 

但至少它们现在每次运行时都是一样的。

import requests 
import pprint 
import threading 
 
def fetch_ev(index, url):  # index parameter added 
    response = requests.get(url) 
    response.raise_for_status() 
    data = response.json() 
    ev_single = data['quoteSummary']['result'][0][ 
                     'defaultKeyStatistics']['enterpriseValue']['raw'] 
    with ev_array_lock: 
        ev_array[index] = ev_single  # store enterprise value obtained 
 
tickers = ['aapl', 'googl', 'nvda'] 
ev_array = [None] * len(tickers)  # preallocate to hold results 
ev_array_lock = threading.RLock()  # to synchronize concurrent array access 
urls = ['https://query2.finance.yahoo.com/v10/finance/quoteSummary/{}' 
        '?formatted=true&crumb=8ldhetOu7RJ&lang=en-US&region=US' 
        '&modules=defaultKeyStatistics%2CfinancialData%2CcalendarEvents' 
        '&corsDomain=finance.yahoo.com'.format(symbol) 
           for symbol in tickers] 
threads = [threading.Thread(target=fetch_ev, args=(i, url)) 
                for i, url in enumerate(urls)]  # activities to obtain ev's 
 
for thread in threads: 
    thread.start() 
for thread in threads: 
    thread.join() 
pprint.pprint(dict(zip(tickers, ev_array)))