【问题标题】:Prevent Overwrite of Nested Dictionary Values while Creating Dictionary in a For Loop在 For 循环中创建字典时防止覆盖嵌套字典值
【发布时间】:2017-12-25 07:38:29
【问题描述】:

我对 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'),'风速':十进制('3.00'), 'winddirection':十进制('310.00')},u'KKLS':{date_obs': datetime.datetime(2017, 7, 19, 16, 56), '温度': 十进制('21.00' '露点:'十进制('4.00'),'高度计':十进制('30.10'), 'windspeed':十进制('3.00'),'winddirection':十进制('310.00')}}

并且想要类似的东西:

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

【问题讨论】:

  • 我看到的一个问题是您拥有的输入字典无效。 date_obs 不在引号中,Decimal('21.00' 没有完全括起来。

标签: python mysql dictionary


【解决方案1】:

您创建一个d 字典:

d = {}

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

D[station] = d

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

因此,当您打印DD['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() 的这个hack 真的很丑……你宁愿使用:

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

使用字典理解。

【讨论】:

    猜你喜欢
    • 2019-02-13
    • 1970-01-01
    • 2021-07-25
    • 2019-03-29
    • 2022-01-03
    • 2020-11-02
    • 1970-01-01
    • 2020-09-13
    • 2023-03-12
    相关资源
    最近更新 更多