所以我有一些列出了来自Mongo的预先计算的值(商店的产品价格平均值)。每个列表代表不同产品的一周。列表可以具有不同的大小,因为有时产品不会在一周内销售。商店的平均子列表在两个不同的星期之间也可以是不同的大小,因为某些商店可能缺货(因此该产品没有任何价格)。
有没有办法获得我的结果而不需要多次for循环?
这是一个有两周时间澄清的例子:
Week1
[{u'_id': 193390, u'avgT': 12, u'avgByS': [{u'S': 7, u'avg': 12}]}, {u'_id': 193396, u'avgT': 29, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]}]
Week2
[{u'_id': 193390, u'avgT': 11, u'avgByS': [{u'S': 7, u'avg': 10}, {u'S': 9, u'avg': 12}]}, {u'_id': 193398, u'avgT': 15, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]},{u'_id': 193396, u'avgT': 29, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]}]
期望输出
[{u'_id': 193390, u'avgT': 11.5, u'avgByS': [{u'S': 7, u'avg': 11}, {u'S': 9, u'avg': 12}]}, {u'_id': 193398, u'avgT': 15, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]},{u'_id': 193396, u'avgT': 29, u'avgByS': [{u'S': 7, u'average': 29}, {u'S': 5, u'average': 29}]}]
答案 0 :(得分:0)
有没有办法获得我的结果而不需要多次for循环?
没有。您的数据结构是列表内的列表。没有...迭代就无法迭代数据。
但嵌套for循环并不总是一个坏主意!一些嵌套的for循环导致O(N ^ 2)行为,但是一些嵌套for循环会导致O(N)行为,这取决于你的实际代码。
以下是计算数据的一种方法。请注意,它有三个嵌套for循环。你无法避免这种情况。但是没有一个嵌套循环导致多项式复杂性。我在big-O上生锈,但我声称以下程序中的聚合循环在O(N)中运行,其中N是avgByS
列表中的值的总数。 (第二个循环的复杂性将等于第一个循环,但我在结果上调用sorted()
。这可能会减慢一些。)
from __future__ import division
from pprint import pprint
weeks = [
[{u'_id': 193390, u'avgT': 12, u'avgByS': [{u'S': 7, u'avg': 12}]}, {u'_id': 193396, u'avgT': 29, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]}],
[{u'_id': 193390, u'avgT': 11, u'avgByS': [{u'S': 7, u'avg': 10}, {u'S': 9, u'avg': 12}]}, {u'_id': 193398, u'avgT': 15, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]},{u'_id': 193396, u'avgT': 29, u'avgByS': [{u'S': 7, u'avg': 29}, {u'S': 5, u'avg': 29}]}]
]
# First, accumlate the data. Convert lists to dicts.
total = {}
for week in weeks:
for product in week:
total_product = total.setdefault(
product['_id'],
{
u'_id':product['_id'],
u'avgT':[],
u'avgByS':{}
})
total_product['avgT'].append(product['avgT'])
for store in product['avgByS']:
total_product['avgByS'].setdefault(store['S'],[]).append(store['avg'])
pprint (total)
# Next, convert dicts to lists and compute averages.
averages = [{
u'_id': k,
u'avgT': sum(v['avgT'])/len(v['avgT']),
u'avgByS': [{
u'S': kk,
u'avg': sum(vv)/len(vv),
}
for kk,vv in sorted(v['avgByS'].items())]
}
for k,v in sorted(total.items())]
pprint(averages)