在For循环中创建字典时阻止覆盖嵌套字典值

时间:2017-07-19 20:40:46

标签: python mysql dictionary

我是Python的新手,我正在尝试编写一个循环现有字典的脚本,并重新组织数据,使其在嵌套字典中。现有字典是根据我在网上找到的一些代码创建的,这些代码将SQL查询中的一行转换为字典。我知道这有点多余,我只是不知道如何编辑这段代码以使其显示我想要的内容。

以下是脚本:https://geert.vanderkelen.org/2010/fetching-rows-as-dictionaries-with-mysql-connectorpython/

无论如何,当我这样做时,嵌套字典会自动覆盖以前嵌套的字典,即使嵌套字典的字典键正在改变。我已经搜索过并发现了一些其他StackOverflow问题但问题仍然存在,但无法为我的代码找到解决方案。

这是我的相关代码:

    row=curs.fetchone
    d={}
    D={}
    while row is not None:
        station=row[u'STATION']
        date_obs=row[u'DATE_OBSERVATION']
        temperature=row[u'TMPC']
        altimeter=row[u'ALTM']
        dewpoint=row[u'DWPC']
        windspeed=row[u'SPED']
        winddirection=row[u'DRCT']
        for i in ('date_obs', 'temperature', 'altimeter', 'dewpoint', 'windspeed', 'winddirection'):
            d[i]=locals()[i]
        D[station]=d
        row = curs.fetchone()
print D

我会得到这样的东西(虽然有更多的字典条目):

  

{u' KBFI':{date_obs':datetime.datetime(2017,7,19,16,56),   温度':十进制(' 21.00''露点:'十进制(' 4.00'),   '高度计':十进制(' 30.10'),' windspeed':十进制(' 3.00'),   ' winddirection&#39 ;:十进制(' 310.00')},你' KKLS':{date_obs':   datetime.datetime(2017,7,19,16,56),'温度':十进制(' 21.00'   '露点:'十进制(' 4.00'),'高度计':十进制(' 30.10'),   ' windspeed&#39 ;:十进制(' 3.00'),' winddirection':十进制(' 310.00')}}

想要类似的东西:

  

{u' KBFI':{date_obs':datetime.datetime(2017,7,19,16,53),   '温度':十进制(' 19.00''露点:'十进制(' 5.00'),   '高度计':十进制(' 30.06'),' windspeed':十进制(' 4.00'),   ' winddirection&#39 ;:十进制(' 270.00')},你' KKLS':{date_obs':   datetime.datetime(2017,7,19,16,56),'温度':十进制(' 21.00'   '露点:'十进制(' 4.00'),'高度计':十进制(' 30.10'),   ' windspeed&#39 ;:十进制(' 3.00'),' winddirection':十进制(' 310.00')}}

1 个答案:

答案 0 :(得分:0)

您使用以下内容创建d字典

d = {}

然后,在每个循环中,您在主D字典中创建一个新条目:

D[station] = d

但每一次,d都指的是同一个字典。您已使用d[i] = ....更新了每个循环中的值,但它仍然保持相同的对象。

因此,当您打印D时,D['KBFI']D['KKLS']会引用相同的字典对象,其值是您在上一个循环中给出的值。

用Python的说法,我们说dict对象是可变的:你可以在不创建新对象的情况下改变它们包含的内容。

为了获得您想要的行为,您可以在每个循环中创建一个新的d

while row is not None:
    station = row[u'STATION']
    # ....
    d = {}  # Here, we create a new dict
    for i in ('date_obs', 'temperature', 'altimeter', 'dewpoint', 'windspeed', 'winddirection'):
        d[i] = locals()[i]
    D[station] = d # D[station] now refers to our new dict

但是locals()的这个黑客真的很难看......你宁愿使用:

D={}

row = curs.fetchone
while row is not None:
    station = row[u'STATION']
    D[station] = {'date_obs': row[u'DATE_OBSERVATION'],
                  'temperature': row[u'TMPC'],
                  'altimeter': row[u'ALTM'],
                  'dewpoint': row[u'DWPC'],
                  'windspeed': row[u'SPED'],
                  'winddirection': row[u'DRCT']
                 }
    row = curs.fetchone()
print D

或者您可以在关键名称和字段名称之间保留一个对应表,并将代码重写为:

fields = {'date_obs': u'DATE_OBSERVATION', 'temperature': u'TMPC'} # and so on...

D={}
row = curs.fetchone
while row is not None:
    station = row[u'STATION']
    D[station] = { key: row[field] for key, field in fields.items() }
    row = curs.fetchone()
print D

使用词典理解。