首页 > 解决方案 > Appending dictionaries when in a for loop

问题描述

Sorry if this has been asked, I've searched a ton and not finding what I'm looking for. Lots of ways to combine dictionaries, but haven't found anything for combining in a loop that applies.

I have a function (masternodes()) that will return a filtered queryset. With each object returned from that queryset, I loop through and query another function (masternodeDetail()) to get some details about that object. The function (masternodeDetail()) returns a dictionary. I'd like to combine the dictionaries returned in to a single dictionary so I can pass that to my template.

Here's my code I've been working with:

def masternodes(request):
  user = request.user
  mn = {}
  queryset = Masternode.objects.filter(created_by=user)    
  for n in queryset:
    mn = masternodeDetail(n.wallet_address, n.coin_symbol)
  print(mn)

  args = {'masternodes': queryset, 'masternodetail': mn}
  return render(request, 'monitor.html', args)

def masternodeDetail(wallet, ticker):
  monitorinfo = MonitorInfo.objects.get(coin_symbol=ticker)
  coin_symbol = monitorinfo.coin_symbol
  daemon = monitorinfo.daemon
  rpc_user = monitorinfo.rpc_user
  rpc_password = monitorinfo.rpc_password
  rpc_port = monitorinfo.rpc_port
  coin_name = monitorinfo.coin_name
  notes = monitorinfo.notes
  masternode_reward = monitorinfo.masternode_reward
  coingecko_id = monitorinfo.coingecko_id
  json_output = monitorinfo.json_output    
  headers = {'content-type': 'text/plain'}
  payload = {"method": "masternodelist", "params": ['full', wallet], "jsonrpc": "1.0", "id": "MN Monitoring v0.1"}
  response = requests.post("http://" + daemon + ":" + rpc_port, json=payload, headers=headers, auth=(rpc_user,rpc_password)).json()    
  res = response["result"]

  if json_output == False:
    for k,v in res.items():
        list = v.split()
        ## status protocol payee lastseen activeseconds lastpaidtime lastpaidblock IP ##
        status = list[0]
        protocol = list[1]
        payee = list[2]
        lastseen = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(float(list[3])))
        activeseconds = datetime.timedelta(seconds=float(list[4]))
        lastpaidtime = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(float(list[5])))
        lastpaidblock = list[6]
        nodeip = list[7].split(':', 1)[0]
        masternode_result = {payee: {'coin':coin_symbol, 'coin_name':coin_name, 'notes':notes, 'masternode_reward':masternode_reward, 
            'coingecko_id':coingecko_id, 'status':status, 'protocol':protocol, 'payee':payee, 'lastseen': lastseen, 
            'activeseconds': activeseconds, 'lastpaidtime': lastpaidtime, 'lastpaidblock': lastpaidblock, 'nodeip': nodeip}}            
        masternodes_result = {**masternode_result, **masternode_result}
        return masternodes_result
  else:        
    for txid in res:
        status = res[txid]['status']
        nodeip = res[txid]['address'].split(':', 1)[0]
        protocol = res[txid]['protocol']
        payee = res[txid]['payee']
        lastseen = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(float(res[txid]['lastseen'])))
        activeseconds = datetime.timedelta(seconds=float(res[txid]['activeseconds']))
        lastpaidtime = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(float(res[txid]['lastpaidtime'])))
        lastpaidblock = res[txid]['lastpaidblock']
        masternode_result = {payee: {'coin':coin_symbol, 'coin_name':coin_name, 'notes':notes, 'masternode_reward':masternode_reward, 
            'coingecko_id':coingecko_id, 'status':status, 'protocol':protocol, 'payee':payee, 'lastseen': lastseen, 
            'activeseconds': activeseconds, 'lastpaidtime': lastpaidtime, 'lastpaidblock': lastpaidblock, 'nodeip': nodeip}}
        masternodes_result = {**masternode_result, **masternode_result}
        return masternodes_result

How can I combine this in to a single dictionary or get all the info I need back to my template? You can see one of my many attempts using the {,} method I've used before but since it's not two different named dictionaries, I'guessing that's why it's not working. Right now, the last dictionary returned from my loop is what's getting passed. Maybe I'm approaching this completely wrong and there's a better way to get this info? Suggestions?

标签: pythondjango

解决方案


我不认为你想要一个“单一的字典”,我无法想象那会是什么样子。相反,您可能想要一个字典列表 - 在这种情况下,您可以这样做:

mn = []
for n in queryset:
    mn.append(masternodeDetail(n.wallet_address, n.coin_symbol))

甚至更短:

mn = [masternodeDetail(n.wallet_address, n.coin_symbol) for n in queryset]

推荐阅读