簡體   English   中英

來自兩個列表的Python字典

[英]Python dictionary from two lists

我有兩個列表,其中一個是值列表,另一個是日期列表。

我想創建一個以值和日期為鍵的字典。 但是許多值具有相同的“鍵”(日期)。 在制作字典之前,我需要將具有相同日期(相同鍵)的值加在一起。

兩個列表具有相同數量的元素,但日期列表具有重復的某些值(因為每個日期均具有多個值)。

根據鍵(日期)對值進行分組(將它們加在一起)的最佳方法是什么?

清單示例

dates = [datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 3, 1, 0, 0),datetime(2014, 3, 1, 0, 0)]

values = [2,7,4,8,4]

I want my dictionary to look like this:
dict = [datetime(2014, 2, 1, 0, 0):13,datetime(2014, 3, 1, 0, 0):8,datetime(2014, 3, 1, 0, 0):4]

如果您有重復的日期,並且希望將重復鍵的值分組,請使用defaultdict

from collections import defaultdict
d = defaultdict(int)
for dte, val in zip(dates, values):
    d[dte] += val

輸出:

defaultdict(<class 'int'>, {datetime.datetime(2014, 2, 1, 0, 0): 13, datetime.datetime(2014, 3, 1, 0, 0): 12})

或使用普通dict和dict.setdefault

d = {}
for dte, val in zip(dates,values):
    d.setdefault(dte,0)
    d[dte] += val

最后,您可以使用默認值為0的dict.get:

d = {}
for dte, val in zip(dates,values):
    d[dte] = d.get(dte, 0) + val

defaultdict將是最快的方法,因為它正是為此目的而設計的。

假設這是您的輸入,

>>> dates = ['2015-01-01', '2015-01-01', '2015-01-02', '2015-01-03']
>>> values = [10, 15, 10, 10]

合並值,

>>> data = zip(dates, values)
[('2015-01-01', 10), ('2015-01-01', 15), ('2015-01-02', 10), ('2015-01-03', 10)]

匯總相同日期的值,

>>> import itertools
>>> new_data = []
>>> for key, group in itertools.groupby(data, lambda x: x[0]):
        tmp = [key, 0]    #: '0' is the default value
        for thing in group:
            tmp[1] += thing[1]
    new_data.append(tmp)

打印new_data

>>> new_data
[['2015-01-01', 25], ['2015-01-02', 10], ['2015-01-03', 10]]

現在建立最終的字典,

>>> dict(new_data)
{'2015-01-03': 10, '2015-01-02': 10, '2015-01-01': 25}

為此, itertoolsdefaultdict完全沒有必要。 我認為這更容易閱讀。

dates = [datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 3, 1, 0, 0),datetime(2014, 3, 1, 0, 0)]
values = [2,7,4,8,4]

combined = {}
for (date,value) in zip(dates,values):
  if date in combined:
    combined[date] += value
  else:
    combined[date] = value

性能分析

我並不是說defaultdict是一個不好的解決方案,我只是指出它需要更多隱性知識才能使用而不會陷入陷阱。

但是,它不是最快的解決方案。

from collections import defaultdict
from datetime import datetime
import timeit

dates = [datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 2, 1, 0, 0),datetime(2014, 3, 1, 0, 0),datetime(2014, 3, 1, 0, 0)]
values = [2,7,4,8,4]

def combine_default_dict(dates=dates,values=values):
  d = defaultdict(int)
  for dte, val in zip(dates, values):
      d[dte] += val
  return d

def combine_setdefault(dates=dates,values=values):
  d = {}
  for dte, val in zip(dates,values):
      d.setdefault(dte,0)
      d[dte] += val
  return d

def combine_get(dates=dates,values=values):
  d = {}
  for dte, val in zip(dates,values):
      d[dte] = d.get(dte, 0) + val
  return d

def combine_contains(dates=dates,values=values):
  d = {}
  for (date,value) in zip(dates,values):
    if date in d:
      d[date] += value
    else:
      d[date] = value
  return d

def time_them(number=100000):
  for func_name in [k for k in sorted(globals().keys()) if k.startswith('combine_')]:
    timer = timeit.Timer("{0}()".format(func_name),"from __main__ import {0}".format(func_name))
    time_taken = timer.timeit(number=number)
    print "{0} - {1}".format(time_taken,func_name)

產量:

>>> time_them()
0.388070106506 - combine_contains
0.485766887665 - combine_default_dict
0.415601968765 - combine_get
0.472551822662 - combine_setdefault

我已經在幾個不同的機器和python版本上嘗試過。 combine_default_dict與競爭combine_setdefault最慢的。 combine_contains一直是最快的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM