2017-10-16 110 views
2

列表的多个列表我有3个DB调用返回同一个名称,代码元组的元组和计数,像这样:合并基于模板

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1))

month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1))

week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1))

我需要将这些全部合并在一起,以便他们拥有姓名,代码并计算每年,每月和每周的计数。

我的问题是,如果没有记录,我需要插入名称和代码和计数的0值。最终产品应该是这样的:

result = (('Windham', '0905', 1, 1, 0), ('Windsor Windham', '7852', 0, 0, 0), ('Washington', '3292', 0, 0, 0), 
      ('Orleans Essex', '44072', 1, 1, 0), ('Addison', '2853', 0), ('Bennington', '3778', 0), 
      ('Fanklin Grand Isle', '5560', 0, 0 0), ('Caledonia', '1992', 0, 0, 0), 
      ('Rutland', '2395', 1, 0, 0), ('Chittendon', '3367', 1, 1, 0), ('Lamoille', '5229',0, 0 0)) 

我试图嵌套循环来检查,如果名字出现在DB调用和模板。如果如果将DB值附加到列表中,如果不附加0

i = 0 
for p in newlist: 
    try: 
     if p[0] == mlist[i][0]: 
      print("HERE: {} {}".format(p[0], mlist[i][0])) 
      p.append(mlist[i][-1]) 
      i += 1 
     else: 
      p.append(0) 
    except IndexError: 
     continue 

这是追加DB值但不是零。我相信必须有更好的方式来做到这一点,并让它实际工作。

编辑

这是根据接收到的答案更新的代码。对我来说,它仍然是一个0

数据替换每个year值:

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '0905', 0), ('Windsor Windham', '7852', 0), ('Washington', '3292', 0), ('Orleans Essex', '44072', 0), ('Chittendon', '18028633367', 1), ('Addison', '12853', 0), ('Bennington', '3778', 0), ('Caledonia', '11992', 0), ('Rutland', '1895', 0), ('Chittendon', '18367', 0), ('Lamoille', '1809', 0), ('Windham', '180905', 0), ('Windsor Windham', '180852', 0), ('Waston', '18022623292', 0), ('Orleans Essex', '18072', 0), ('Addison', '1853', 0), ('Bennington', '1778', 0), ('Fanklin Grand Isle', '18560', 0), ('Caledonia', '180292', 0), ('Rutland', '195', 0), ('Lamoille', '18229', 0)) 

month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '18028633367', 1)) 

week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '18367', 1)) 

代码:

from collections import defaultdict 
joined_data = defaultdict([0, 0, 0].copy) 

for entry in year: 
    # we create the default entry by calling the defaultdict with a key 
    # and immediately grab the newly created list 
    count = joined_data[(entry[0],entry[1])] 
    # we swap *inplace* the value given by the DB query 
    count[0] = entry[2] 

# rinse and repeat with the rest of the data 
for entry in month: 
    count = joined_data[(entry[0], entry[1])] 
    count[1] = entry[2] 

for entry in week: 
    count = joined_data[(entry[0], entry[1])] 
    count[2] = entry[2] 

# Finally we format the data to the required format 
result = tuple(key+tuple(value) for key,value in joined_data.items()) 
print(result) 

结果:

(('Fanklin Grand Isle', '5560', 0, 1, 1), ('Windham', '0905', 0, 0, 0), ('Windsor Windham', '7852', 0, 0, 0), ('Washington', '3292', 0, 0, 0), ('Orleans Essex', '1072', 0, 0, 0), ('Chittendon', '13367', 0, 1, 1), ('Addison', '2853', 0, 0, 0), ('Bennington', '1878', 0, 0, 0), ('Caledonia', '1992', 0, 0, 0), ('Rutland', '2395', 0, 0, 0), ('Lamoille', '5229', 0, 0, 0))

+0

当然,所有这些城市获得了'0'因为如果一年一年-count在您的“年份”列表中为“0”。你期望输出什么,为什么? –

+0

对不起tobias并不意味着编辑您的文章,意味着编辑我 – Joe

回答

0

这里有一个方式使用defaultdict以避免关心缺少的条目来处理您的问题:

year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1)) 
month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 

#I'm using a defaultdict to deal with the missing entries 
from collections import defaultdict 
joined_data = defaultdict([0,0,0].copy) 

for entry in year: 
    #we create the default entry by calling the defaultdict with a key 
    #and immediately grab the newly created list 
    count = joined_data[(entry[0],entry[1])] 
    #we swap *inplace* the value given by the DB query 
    count[0] = entry[2] 

#rinse and repeat with the rest of the data 
for entry in month: 
    count = joined_data[(entry[0],entry[1])] 
    count[1] = entry[2] 

for entry in week: 
    count = joined_data[(entry[0],entry[1])] 
    count[2] = entry[2] 

#Finally we format the data to the required format 
result = tuple(key+tuple(value) for key,value in joined_data.items()) 
print(result) 

输出:

>>>(('Chittendon', '3367', 0, 1, 1), ('Fanklin Grand Isle', '5560', 1, 1, 1), ('Windham', '3457', 1, 0, 0)) 
+0

这看起来很有希望,我测试了一半,它似乎很好。我将有机会尽快完成测试,如果它能正常工作,请将此标记为答案。谢谢! – Joe

+0

即使在那里应该有一个值,这仍然将结果中的每年输入设置为0。 – Joe

+1

@Joe这是如何“每年设置为0”?富兰克林和温德姆显然有一些1,与我的结果相同。请编辑您的问题并提供一些完整一致的输入和输出数据。 –

0

不知道我理解作为您的示例输入,您试图实现的目标是n OT真正符合你的输出,但我认为你可以使用列表理解来构造的结果,检查这些项目是否在yearsmonthsweeks名单,并增加了10分别为:

>>> year = (('Fanklin Grand Isle', '5560', 1), ('Windham', '3457', 1)) 
>>> month = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
>>> week = (('Fanklin Grand Isle', '5560', 1), ('Chittendon', '3367', 1)) 
>>> [(x[0], x[1], int(x in year), int(x in month), int(x in week)) for x in set(year + week + month)] 
[('Chittendon', '3367', 0, 1, 1), 
('Windham', '3457', 1, 0, 0), 
('Fanklin Grand Isle', '5560', 1, 1, 1)] 

如果这些罪名实际上可以从1是不同的,你应该先创建一些字典映射城市各自的年/月/周数,然后使用类似的列表理解如上:

>>> year_counts = {(name, code): count for (name, code, count) in year} 
>>> month_counts = {(name, code): count for (name, code, count) in month} 
>>> week_counts = {(name, code): count for (name, code, count) in week} 
>>> all_cities = [(name, code) for (name, code, count) in set(year + month + week)] 
>>> [(x[0], x[1], year_counts.get(x, 0), month_counts.get(x, 0), week_counts.get(x, 0)) for x in all_cities] 
[('Chittendon', '3367', 0, 1, 1), 
('Windham', '3457', 1, 0, 0), 
('Fanklin Grand Isle', '5560', 1, 1, 1)] 
+0

我正在尝试创建一个报告,显示每个位置的来电计数,按年份,月份和日期分列。问题是,这些是三个独立的数据库调用,所以我需要合并所有在一起,如果缺少一个位置插入名称和0s – Joe

+0

@Joe这个问题很明显,但我收集,我的第一个猜测没有击中现货呢。现在怎么样?如果这仍然不是你想要的,请尝试澄清这个问题。 –

+0

我需要每个结果都是唯一的,所以我可以通过电子邮件将报告发送给客户。所以它应该有'姓名,代码,年数,月数,星期数'格式。当我运行脚本 – Joe