2

我有一个元组列表,每个元组代表一个日期和当天的相关值。例如

team_effort = [('2012-09-10', 27), ('2012-09-11', 28), 
               ('2012-09-12', 28), ('2012-09-13', 31), ('2012-09-14', 31)]

我需要计算每天之间的值差异,并返回一个类似的元组列表,每个元组都有一个日期和值(如果值相同或减少,则返回 0,如果增加则返回差异)

所以在这个例子中我想返回

[('2012-09-10', 0), ('2012-09-11', 1), 
 ('2012-09-12', 0), ('2012-09-13', 3), ('2012-09-14', 0)]

以下列表理解有效(在 2.4+ 中)

[(data[0], 0) if i == 0
    else (data[0], data[1] - team_effort[i-1][1]) if data[1] > team_effort[i-1][1]
    else (data[0], 0)
    for i, data in enumerate(team_effort)]

但我认为可能有更优雅的解决方案?有什么建议么?

注意我必须区别对待努力数据[0],因为它总是为零,如果它到达努力数据[i-1][1]行,它将查看列表中的最后一项(又名努力数据[-1 ][1]。

4

6 回答 6

1
print (
    [(team_effort[0][0], 0)] +
    [(date[0], max(date[1] - prev_date[1], 0))
        for date, prev_date in zip(team_effort[1:], team_effort[:-1])])
于 2013-08-13T13:15:41.830 回答
1

第一次修订试图使逻辑规范清晰。

increases = []
for i, data in enumerate(effort_data):
    if i == 0:
        # can't increase with no prior
        increases.append((data[0], 0))
        continue
    prior_effort = effort_data[i-1][1]
    if data[1] > prior_effort:
        increases.append((data[0], data[1] - prior_effort))
    else:
        increases.append((data[0], 0))

其实,比起别人发的单行本,我还是忍一忍吧。简单胜于复杂。可读性很重要。

于 2013-08-13T13:27:03.473 回答
1
team_effort = [('2012-09-10', 27), ('2012-09-11', 28), 
               ('2012-09-12', 28), ('2012-09-13', 31), ('2012-09-14', 31)]

numbers = [b for a,b in team_effort]
#[0] because first item has no previous item to subtract from
differences = [0]+[max(b - a,0) for a,b in zip(numbers,numbers[1:])]
print [(a,c) for ((a,b),c) in zip(team_effort, differences)]
#=> [('2012-09-10', 0), ('2012-09-11', 1), ('2012-09-12', 0), ('2012-09-13', 3), ('2012-09-14', 0)]

您可以在一行中完成此操作,但我认为将其拆分会更容易阅读。这是单线:

[(team_effort[0][0],0)]+[(c, max(d-b,0)) for (a,b),(c,d) in zip(team_effort,team_effort[1:])]
于 2013-08-13T13:33:31.557 回答
0
z = zip(team_effort, team_effort[1:])
[(team_effort[0][0], 0)] +
[(d, v2 - v1 if v2 > v1 else 0) for (_, v1), (d, v2) in z]
于 2013-08-13T13:21:50.043 回答
0

enumerate您可以使用第一个元素的特殊条件来简化它:

l = team_effort
[(j[0],0) if i==0 else (j[0],max(0,l[i][1]-l[i-1][1])) for i,j in enumerate(l)]

如果它是第一项 ( i==0),它将添加(date,0).

对于下一个项目,它将通过函数比较差异ii-1仅在它高于零时使用它。max()

#[('2012-09-10', 0),
# ('2012-09-11', 1),
# ('2012-09-12', 0),
# ('2012-09-13', 3),
# ('2012-09-14', 0)]
于 2013-08-13T13:22:39.803 回答
0

干得好。我认为这是非常可读的

team_effort = [('2012-09-10', 27), ('2012-09-11', 28), ('2012-09-12', 28), ('2012-09-13', 31), ('2012-09-14', 31)]

result = []
result.append(( team_effort[0][0], 0) )
for i in range(1, len(team_effort)):

    last_value = team_effort[i-1][1]
    current_value = team_effort[i][1]
    if current_value > last_value:
        result.append(( team_effort[i][0] , current_value - last_value) )
    else:
        result.append(( team_effort[i][0] , 0) )

print result
于 2013-08-13T13:21:35.980 回答