Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将元素添加到键';有序字典中的s值_Python_List_Dictionary - Fatal编程技术网

Python 将元素添加到键';有序字典中的s值

Python 将元素添加到键';有序字典中的s值,python,list,dictionary,Python,List,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',]

我有一本有序的字典:

{'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'对象没有行的属性“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) 所有的值都是列表,而不是字符串和列表的混合。

我认为问题在于代码的最后一行。您确实为变量
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
类,将该值转换为insert上的列表,同时保留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元组(年、月、日)更好地表示日期。这是不可变的,所以它可以是您的dict密钥。(列表是可变的,不能是dict键)


您可以将月份分组逻辑添加到insert方法,也可以将该逻辑移到代码中的其他位置。

这里是一个更好的方法。给定一个{str:str}类型的dict,我们可以通过扩展内置的
dict
类,将该值转换为insert上的列表,同时保留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元组(年、月、日)更好地表示日期。这是不可变的,所以它可以是您的dict密钥。(列表是可变的,不能是dict键)


您可以将月份分组逻辑添加到insert方法中,也可以将该逻辑移到代码中的其他位置。

我看不出在此处使用字符串作为键来表示日期有任何好处。这是我的解决方案,但我希望它不会破坏您当前的代码

好的,您的代码显示您在那里进行了大量嵌套:

 val.append(list(collection.pop(key)))
以及:

键是日期:yyyy-mm-dd,我想在一个键中存储一个月的所有值:

{'20140106': '82.1000000',
 '20140217': ['77.0300000','69.6200000',]
 '20140310': '46.3300000',
 '20140414': '49.3800000',
以下是一种方法: 为此,请使用元组:

mydict = {(year, month, day): value}
这样不仅可以简化问题,还可以提高代码的可读性:

for date in mydict: 
    year  = date[0] 
    month = date[1] 
         ...
    ...process data...

虽然键只能是不可变的对象,但元组是不可变的对象

我不认为在这里使用字符串作为键来表示日期有什么好处。这是我的解决方案,但我希望它不会破坏您当前的代码

好的,您的代码显示您在那里进行了大量嵌套:

 val.append(list(collection.pop(key)))
以及:

键是日期:yyyy-mm-dd,我想在一个键中存储一个月的所有值:

{'20140106': '82.1000000',
 '20140217': ['77.0300000','69.6200000',]
 '20140310': '46.3300000',
 '20140414': '49.3800000',
以下是一种方法: 为此,请使用元组:

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)

为什么不使用
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)

在最后一行中,您正在用字符串覆盖
val
collection.get(上一个_键)
返回一个字符串。在最后一行中,您正在用字符串覆盖
val
collection.get(上一个_键)
返回一个字符串。是的,它是!你能对算法的位置性提出一些建议吗?我非常喜欢你的解决方案,是的!你能对算法的定位提出一些建议吗?我非常喜欢你的解决方案。我的程序逻辑让我忽略了这一年(它是排序的,我可以只收集月的局部常量范围内的所有值。它真的要在类实现中做得更好吗?O_OAlso,你怎么做:
如果不是isinstance(self.get(key),list):
@VladislavLa