[英]Adding an element to the key's value in ordered dictionary
我有一个有序的字典:
{'20140106': '82.1000000',
'20140217': '77.0300000',
'20140224': '69.6200000',
'20140310': '46.3300000',
'20140414': '49.3800000',
键是日期:yyyy-mm-dd,我想在一个键中存储一个月的所有值:
{'20140106': '82.1000000',
'20140217': ['77.0300000','69.6200000',]
'20140310': '46.3300000',
'20140414': '49.3800000',
我意识到这不是一个非常美妙的解决方案:
val = [] #list, where i put all values for an exact month
previus_key = list(collection.keys())[0]
val.append(collection.get(previus_key))
for key in list(collection.keys())[1:]:
if (key[4:6]==previus_key[4:6]): #if it's the same month
val.append(list(collection.pop(key))) #remember the value and delete an item
else:
collection.update({previus_key:val}) #that means, we jumped to another month, so lets update the values for previus month
previus_key = key #now, start the same algorihtm for a new month.
val = collection.get(previus_key)
但是,我得到一个错误: 'str' object has no attribute 'append'
为行val.append(list(collection.pop(key)))
。 我研究了它,并得出结论,它一定不能在这里! 因为,我将列表附加到列表中! 所以,请指出我的错误并给出建议,我怎样才能使代码更美观。 谢谢!
我认为问题在于代码的最后一行。 你确实为那里的变量var
分配了一个字符串。
编辑:这是一个与原始代码保持一致的建议。
new_collection = {}
for key in collection:
month = key[:6]
if new_collection.get(month) != None:
new_collection[month].append(collection[key])
else:
new_collection[month] = [collection[key]]
三件事:1)这里的结果是一个新的字典,而不是相同的实例,因为我发现它通常更可取。 2)密钥只是年份和月份,因为这一天是无关紧要的。 3)所有值都是列表,而不是字符串和列表的混合。
这是一个更好的方法。 给定类型为{str:str}的字典,我们可以将值转换为插入列表,同时通过扩展内置的dict
类来保留dict的所有功能。
这是一个演示。
>>> class CustomDict(dict):
... def insert(self, key, val): # add a new method, `insert`
... if self.get(key):
... if not isinstance(self.get(key), list):
... lst = []
... lst.append(self.get(key))
... lst.append(val)
... self[key] = lst[:] # copy list
... else:
... self[key].append(val)
... else:
... self[key] = val
...
>>> vars = {'19900326': '372.99101',
... '19730529': '291.38291',
... '19430122': '81.248291',
... '19930227': '192.32919',}
>>> vars2 = CustomDict(vars)
>>> vars2
{'19730529': '291.38291',
'19900326': '372.99101',
'19430122': '81.248291',
'19930227': '192.32919'}
>>> vars2.insert('19730529', '102.88391')
>>> vars2
{'19730529': ['291.38291', '102.88391'],
'19900326': '372.99101',
'19430122': '81.248291',
'19930227': '192.32919'}
在您的情况下,您将希望从collections.ordereddict继承
至于想要将同一个月的所有数据存储在同一列表中的逻辑,您可以很容易地在那里编写代码。 但是可以肯定的是,看起来你现在完全无视年份了。 你确定你所关心的是同一个月,即使这些数据来自不同的年份吗? 如果没有,您应该更改逻辑,以便区分哪一年。
有人建议更好地表示日期,作为3元组(year, month, day)
。 这是不可变的,所以它可以是你的dict键。 (列表是可变的,不能是dict键)。
您可以将月份分组逻辑添加到insert方法,或者您可以将该逻辑移动到代码中的其他位置。
我没有看到在这里使用字符串作为表示日期的键的任何优点。 这是我的解决方案,但我希望它不会破坏您当前的代码。
好吧,你的代码显示你在那里做了很多嵌套:
val.append(list(collection.pop(key)))
和:
键是日期:yyyy-mm-dd,我想在一个键中存储一个月的所有值:
这是一种方法:使用元组实现此目的:
mydict = {(year, month, day): value}
这样不仅可以简化问题,还可以使代码更具可读性:
for date in mydict:
year = date[0]
month = date[1]
...
...process data...
虽然键只能是不可变对象,但是元组是不可变对象。
为什么不使用reduce
和filter
功能。 reduce
会将函数应用于迭代对象中的每个项目,您还可以指定reduce
的初始值
from collections import OrderedDict
a = {'20140106': '82.1000000', '20140217': '77.0300000', '20140224': '69.6200000', '20140310': '46.3300000', '20140414': '49.3800000'}
def aggr(result, item):
key = filter(lambda x: x[:6] == item[0][:6], result.keys())
if not key:
result[item[0]] = [item[1]]
else:
result[key[0]].append(item[1])
return result
r = OrderedDict()
print reduce(aggr, a.items(), r)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.