Python 列表列表+;环
我有这样一个列表:Python 列表列表+;环,python,list,function,loops,Python,List,Function,Loops,我有这样一个列表: list = [[year1-month1,int1,float1],[year1-month1,int2,float2],[year1-month2,int3,float3].... 我需要定义一个函数,通过它返回如下结果: newList = [[((int1*float1)+(int2*float2))/(float1+float2),year-month1],... 我的问题是,2000多个子列表中的第一项是一个年-月格式的日期,其余的是天的值,我需要得到月平均值
list = [[year1-month1,int1,float1],[year1-month1,int2,float2],[year1-month2,int3,float3]....
我需要定义一个函数,通过它返回如下结果:
newList = [[((int1*float1)+(int2*float2))/(float1+float2),year-month1],...
我的问题是,2000多个子列表中的第一项是一个年-月格式的日期,其余的是天的值,我需要得到月平均值。我尝试了几件事,但都没能成功。如能提出一些建议,我将不胜感激
我试过的是:
def avPrice(mylist):
month=[]
i = 0
for i in mylist:
if mylist[i][0] not in month:
month = mylist[i][0],mylist[i][1]*mylist[i][2],mylist[i][2]
else:
month = month[0],month[1]+(mylist[i][1]*mylist[line][2]),month[2]+mylist[i][2]
i = i + 1
return month
monthAvPrice.append(month)
我知道可能有更好的方法,但是你试过使用for循环吗
def monthly_average(list):
newList=[]
for i in range(len(list)/2):
avg=((list[i][1]*list[i][2])+(list[i+1][1]+list[i+1][2]))
avg=avg/(list[i][2]+list[i+1][2])
newList.append(avg)
newList.append(list[i][0])
return newList
假设您每个月有两个子列表,这应该是可行的。如果有更多,则可能需要添加一个函数来检查“第零个”索引等于某个字符串的所有子列表。例如:
newList=[]
tempList=[]
for i in list:
if i[0]=='year1-month1':
tempList.append(i)
while len(tempList)>1:
tempList=monthly_average(tempList)
import itertools
ddat= [['2012-01', 1, 5.4], ['2012-01', 2, 8.1], ['2012-01', 3, 10.8],
['2012-01', 4, 13.5], ['2012-02', 1, 8.1], ['2012-02', 2,10.8],
['2012-02', 3, 13.5], ['2012-02', 4, 16.2], ['2012-03', 1, 10.8],
['2012-03', 2, 13.5], ['2012-03', 3, 16.2], ['2012-03', 4, 18.9],
['2012-04', 1, 13.5], ['2012-04', 2, 16.2], ['2012-04', 3,18.9]]
[[w[0], reduce(lambda x, y: x+y[1]*y[2], list(w[1]), 0)] for w in itertools.groupby(ddat, key=lambda x:x[0])]
然后每个月迭代一次,更改字符串值
再说一次,这可能不是最有效的方法,但它很有效。我知道可能有更好的方法,但您是否尝试过使用for循环
def monthly_average(list):
newList=[]
for i in range(len(list)/2):
avg=((list[i][1]*list[i][2])+(list[i+1][1]+list[i+1][2]))
avg=avg/(list[i][2]+list[i+1][2])
newList.append(avg)
newList.append(list[i][0])
return newList
假设您每个月有两个子列表,这应该是可行的。如果有更多,则可能需要添加一个函数来检查“第零个”索引等于某个字符串的所有子列表。例如:
newList=[]
tempList=[]
for i in list:
if i[0]=='year1-month1':
tempList.append(i)
while len(tempList)>1:
tempList=monthly_average(tempList)
import itertools
ddat= [['2012-01', 1, 5.4], ['2012-01', 2, 8.1], ['2012-01', 3, 10.8],
['2012-01', 4, 13.5], ['2012-02', 1, 8.1], ['2012-02', 2,10.8],
['2012-02', 3, 13.5], ['2012-02', 4, 16.2], ['2012-03', 1, 10.8],
['2012-03', 2, 13.5], ['2012-03', 3, 16.2], ['2012-03', 4, 18.9],
['2012-04', 1, 13.5], ['2012-04', 2, 16.2], ['2012-04', 3,18.9]]
[[w[0], reduce(lambda x, y: x+y[1]*y[2], list(w[1]), 0)] for w in itertools.groupby(ddat, key=lambda x:x[0])]
然后每个月迭代一次,更改字符串值
再说一遍,这可能不是最有效的方法,但它确实有效。以下是我的想法
def appendDateNumbers(d, item):
def sumItem(date, integer, floating, *junk):
if date in d:
d[date]+=integer*floating
else:
d[date]=integer*floating
return d
return sumItem(*item)
def _averageListWith(dn, datesList):
def averageItem(i):
return (i, dn[i]/datesList.count(i))
return dict(map(averageItem, dn.keys()))
def averageLst(lst):
return _averageListWith(reduce(appendDateNumbers, lst, {}),
map(lambda x: x[0], lst))
print averageLst([["12-12", 1, 1.0],["12-12", 2, 2.2],["13-1", 3, 3.3]])
averageLst()函数应该为您提供加减舍入误差的服务。以下是我的建议
def appendDateNumbers(d, item):
def sumItem(date, integer, floating, *junk):
if date in d:
d[date]+=integer*floating
else:
d[date]=integer*floating
return d
return sumItem(*item)
def _averageListWith(dn, datesList):
def averageItem(i):
return (i, dn[i]/datesList.count(i))
return dict(map(averageItem, dn.keys()))
def averageLst(lst):
return _averageListWith(reduce(appendDateNumbers, lst, {}),
map(lambda x: x[0], lst))
print averageLst([["12-12", 1, 1.0],["12-12", 2, 2.2],["13-1", 3, 3.3]])
averageLst()函数应该为您提供加减舍入错误。使用itertools.groupby()将条目分组一个月,使用reduce()将数字相加。例如:
newList=[]
tempList=[]
for i in list:
if i[0]=='year1-month1':
tempList.append(i)
while len(tempList)>1:
tempList=monthly_average(tempList)
import itertools
ddat= [['2012-01', 1, 5.4], ['2012-01', 2, 8.1], ['2012-01', 3, 10.8],
['2012-01', 4, 13.5], ['2012-02', 1, 8.1], ['2012-02', 2,10.8],
['2012-02', 3, 13.5], ['2012-02', 4, 16.2], ['2012-03', 1, 10.8],
['2012-03', 2, 13.5], ['2012-03', 3, 16.2], ['2012-03', 4, 18.9],
['2012-04', 1, 13.5], ['2012-04', 2, 16.2], ['2012-04', 3,18.9]]
[[w[0], reduce(lambda x, y: x+y[1]*y[2], list(w[1]), 0)] for w in itertools.groupby(ddat, key=lambda x:x[0])]
产生
[['2012-01', 108.0],
['2012-02', 135.0],
['2012-03', 162.0],
['2012-04', 102.6]]
[['2012-01', 37.8, 108.0, 2.857142857142857],
['2012-02', 48.6, 135.0, 2.777777777777778],
['2012-03', 59.4, 162.0, 2.7272727272727275],
['2012-04', 48.6, 102.6, 2.111111111111111]]
编辑:以上仅获取所需值的分子。下面显示的代码同时计算分子和分母。作为演示代码,它生成一个包含值及其比率的列表
请注意以下代码中的明显额外。(即,部分
…对于w,v in[[w,list(v)],对于w,v in itertools…
在第三行代码中。)for
的的额外层用于将iterablev
作为列表进行复制。也就是说,由于itertools.groupby()返回的v
是一个iterable而不是实际列表,numerium sum(v)
将耗尽v
,因此denom sum(v)
将得到一个0的值。另一种方法是使用itertools.tee;但对于另一个问题,list
方法可能更快。第三种可能是将numer\u sum
和denom\u sum
组合成一个返回元组的单一函数,并为
添加一个外部,以计算比率
def numer_sum(w): return reduce(lambda x,y: x+y[1]*y[2], w, 0)
def denom_sum(w): return reduce(lambda x,y: x+y[2], w, 0)
[[w, round(denom_sum(v),3), numer_sum(v), numer_sum(v)/denom_sum(v)] for w,v in [[w, list(v)] for w,v in itertools.groupby(ddat, key=lambda x:x[0])]]
产生
[['2012-01', 108.0],
['2012-02', 135.0],
['2012-03', 162.0],
['2012-04', 102.6]]
[['2012-01', 37.8, 108.0, 2.857142857142857],
['2012-02', 48.6, 135.0, 2.777777777777778],
['2012-03', 59.4, 162.0, 2.7272727272727275],
['2012-04', 48.6, 102.6, 2.111111111111111]]
使用itertools.groupby()将条目分组一个月,使用reduce()将数字相加。例如:
newList=[]
tempList=[]
for i in list:
if i[0]=='year1-month1':
tempList.append(i)
while len(tempList)>1:
tempList=monthly_average(tempList)
import itertools
ddat= [['2012-01', 1, 5.4], ['2012-01', 2, 8.1], ['2012-01', 3, 10.8],
['2012-01', 4, 13.5], ['2012-02', 1, 8.1], ['2012-02', 2,10.8],
['2012-02', 3, 13.5], ['2012-02', 4, 16.2], ['2012-03', 1, 10.8],
['2012-03', 2, 13.5], ['2012-03', 3, 16.2], ['2012-03', 4, 18.9],
['2012-04', 1, 13.5], ['2012-04', 2, 16.2], ['2012-04', 3,18.9]]
[[w[0], reduce(lambda x, y: x+y[1]*y[2], list(w[1]), 0)] for w in itertools.groupby(ddat, key=lambda x:x[0])]
产生
[['2012-01', 108.0],
['2012-02', 135.0],
['2012-03', 162.0],
['2012-04', 102.6]]
[['2012-01', 37.8, 108.0, 2.857142857142857],
['2012-02', 48.6, 135.0, 2.777777777777778],
['2012-03', 59.4, 162.0, 2.7272727272727275],
['2012-04', 48.6, 102.6, 2.111111111111111]]
编辑:上面只获取所需值的分子。下面显示的代码同时计算分子和分母。作为演示代码,它生成一个包含值及其比率的列表
请注意以下代码中明显额外的(即部分
…对于w,v in[[w,list(v)],对于w,v in itertools…
在第三行代码中。)for
的的额外层用于将iterablev
作为列表进行复制。也就是说,由于itertools.groupby()返回的v
是一个iterable而不是实际列表,numerium sum(v)
将耗尽v
,因此denom sum(v)
将得到一个0的值。另一种方法是使用itertools.tee;但对于另一个问题,list
方法可能更快。第三种可能是将numer\u sum
和denom\u sum
组合成一个返回元组的单一函数,并为
添加一个外部,以计算比率
def numer_sum(w): return reduce(lambda x,y: x+y[1]*y[2], w, 0)
def denom_sum(w): return reduce(lambda x,y: x+y[2], w, 0)
[[w, round(denom_sum(v),3), numer_sum(v), numer_sum(v)/denom_sum(v)] for w,v in [[w, list(v)] for w,v in itertools.groupby(ddat, key=lambda x:x[0])]]
产生
[['2012-01', 108.0],
['2012-02', 135.0],
['2012-03', 162.0],
['2012-04', 102.6]]
[['2012-01', 37.8, 108.0, 2.857142857142857],
['2012-02', 48.6, 135.0, 2.777777777777778],
['2012-03', 59.4, 162.0, 2.7272727272727275],
['2012-04', 48.6, 102.6, 2.111111111111111]]
您可以编辑您的答案以包含您尝试过的一些内容吗?也许我们可以帮助您在代码中找到问题。您可以编辑您的答案以包含您尝试过的一些内容吗?也许我们可以帮助您在代码中找到问题。我没有想到使用groupby。打得好。我没有想到使用groupby。打得好。