在Python中,动态分配字典条目

时间:2014-05-07 18:11:18

标签: python dictionary

在下面的代码中,我有一个字典“John”,我为某个键(“电话号码”)分配了一个值:

John={}
statement='John'+"['phone number']=123456"
exec statement

我之所以选择“exec”,是因为实际字典“John”和“电话号码”应该在for循环中变化。这有效,但不是很优雅;我宁愿做类似

的事情
vars()['John'+'_phone_number']=123456

因为在这种情况下,如果语法不正确,则不会冒“exec”语句失败的风险。 (我想要实现的是类似于Matlab的“assignin”函数,除了字典条目)。

有没有一种方法可以在不使用“exec”的情况下定义字典的条目?

3 个答案:

答案 0 :(得分:4)

我认为你应该使用字典词典。您甚至可以使用defaultdict来避免为每个用户预先设置每个条目。

from collections import defaultdict

users = defaultdict(dict)
users['John']['phone number'] = 123456

答案 1 :(得分:1)

我认为defaultdict在这里是一个坏主意...我很确定所有用户都应该拥有相同的密钥(例如,所有用户应该是电话号码和电子邮件,或者user_id或每个用户使用相同的密钥

users = {}
for name,phone,email in [("john","123","a@b"),("mary","432","b@b"),...]:
    users[name] = dict(email=email,phone=phone)

或者如果您打算使用默认dict,至少要确保它具有用户的所有必填字段

def my_user_dict():
    return {"email":"","phone":""}

users = defaultdict(my_user_dict)

答案 2 :(得分:0)

虽然看起来多数人觉得要走的路是使用嵌套词典 - 而且我会接受这个答案 - 在我自己的代码中,我决定坚持使用&#34这种不那么优雅的方式; EXEC"声明。代码 - 实际上不是用户和电话号码,而是确定和存储某些曲线的数学属性 - 如下所示:

import numpy as np
import matplotlib.pyplot as plt

# CSV file generated from nDI by Data Export -> ASCII with "Export as CSV" ticked on
filename="lnb.1t_LNB-1_wedge_amplitude_extractions.csv"

# Read column headers (to be variable names)
with open(filename) as f:
    firstline = f.readline()                    # Read first line of csv
    firstline = firstline.replace("\n","")      # Remove new line characters
    firstline = firstline.replace(" ","")       # Remove spaces
    ColumnHeaders = firstline.split(",")        # Get array of column headers

# Read in the data (omitting the first row containing column headers)
data=np.loadtxt(filename,skiprows=1,delimiter=",")

N_leg=50        # Number of traces 'pure' gas leg and brine leg

# Assign the data to arrays, with names of the variables generated from column headers
Ind=0                                       # Initialize counter
for Var in ColumnHeaders:
    vars()[Var]=data[:,Ind]                 # Create an array for each column, named after the corresponding column header
    if Var.endswith("_evnt_amp"):           # For columns with headers containing the suffix '_evnt_amp' ('event amplitude'):
        Event=Var.strip("_evnt_amp")        # Define a string containing the event name
        vars()[Event]={}                    # Initialize an empty dictionary
        statement1=Event+"['gas leg amplitude']=np.mean(data[0:N_leg,Ind])"
        exec statement1
        statement2=Event+"['brine leg amplitude']=np.mean(data[-N_leg:-1,Ind])"
        exec statement2
        statement3=Event+"['gas to brine leg ratio']=np.mean(data[0:N_leg,Ind])/np.mean(data[-N_leg:-1,Ind])"
        exec statement3
##        vars()[Var+'_gas_leg']=data[0:N_leg,Ind]
##        vars()[Var+'_brine_leg']=data[-N_leg:-1,Ind]
##        vars()[Var.strip('_evnt_amp')+'_gas_leg_amplitude']=np.mean(data[0:N_leg,Ind])
##        vars()[Var.strip('_evnt_amp')+'_brine_leg_amplitude']=np.mean(data[-N_leg:-1,Ind])
    Ind=Ind+1                               # Increment counter

plt.close('all')

plt.figure(1)
plt.plot(Bin,ROSLU_T_evnt_amp,'c')
plt.plot(Bin,-DC_T_evnt_amp,'m')
plt.xlabel('Bin')
plt.ylabel('|Amplitude|')
plt.legend(['ROSLU_T','DC_T'])

plt.show()

相关部分是" exec"的for循环。声明。 (我已经注释掉了它们下方的过时行,这些行通过附加后缀而不是创建字典来工作。)

运行此代码后,我可以在命令行中键入事件的名称,并读取其中的几个属性:

>>> ROSLU_T
{'gas to brine leg ratio': 2.1782322499999998, 'gas leg amplitude': 174.25857999999997, 'brine leg amplitude': 80.0}

作为参考,我已经粘贴了以下输入csv文件的一部分:

Track,Bin,ZEZ2A_T_evnt_amp,RO_T_evnt_amp,ROSLU_T_evnt_amp,DC_T_evnt_amp               1,1,-1288.4139,999.9983,174.1523,-201.6915               1,2,-1288.4139,999.9983,174.1523,-201.6915               1,3- -1288.4139,999.9983,174.1523,-201.6915               1,4,-1288.4139,999.9983,174.1523,-201.6915               1,5,-1288.4139,999.9983,

此代码生成的图表如下所示。

wedge model amplitude extractions