2016-02-24 15 views
6

tôi cố gắng xử lý dữ liệu như:Python tính toán chạy tổng các giá trị trong một dòng

some_data = [ 
       {'value': 2, 'date':'2016-02-06'}, 
       {'value': 1, 'date':'2016-02-07'}, 
       {'value': 5, 'date':'2016-02-08'}, 
       {'value': 3, 'date':'2016-02-09'}, 
       {'value': 1, 'date':'2016-02-10'}, 
      ] 

Vì vậy mà nó tạo ra một danh sách với giá trị được cập nhật để trở thành một tổng chạy. Bây giờ tôi làm điều đó với một vòng lặp multiline:

def values_incremented(some_data): 
    temp_sum = 0 
    result = [] 
    for element in some_data: 
     temp_sum += element['value'] 
     result.append({'value': temp_sum, 'date': element['date']}) 
    return result 

Làm thế nào để làm cho vòng một lót, vì vậy mà tôi nhận:

return [{'value': somehow_incremented, 'date': element['date']} for element in some_data] 
+0

Đầu ra mong muốn của bạn là gì? Bạn đang nhận được gì? –

+1

@ nathan.meadows: đọc lại câu hỏi. –

+0

Bạn có hai dòng trong vòng lặp for và Bạn muốn một dòng. Tôi có hiểu đúng không? – AlokThakur

Trả lời

3

tôi sẽ không khuyên bạn nên làm bất cứ điều gì , mã của bạn là tốt. Giữ cho nó dễ đọc.

đó đang được nói, đây là một cách tiếp cận:

def values_incremented(some_data): 
    return [{'value': current_sum, 'date': element['date']} 
     for element, current_sum 
     in zip(some_data, 
      reduce(lambda x, y: [y['value']] if not x else x + [x[-1] + y['value']], some_data, []))] 
+0

Đây là một TRUE một lớp lót :) Cảm ơn :) Và có, bạn phải, mã ban đầu là dễ đọc hơn nhiều. Những gì tôi đã cố gắng là để giảm bớt các khai báo dự phòng, chẳng hạn như 'temp_sum = 0' và' result = [] ' – alekwisnia

+0

Vâng, tính toán số tiền lăn làm cho nó khó xử. Chỉ cần nhìn nó lên ... không ai trong số họ trông sạch sẽ inlined: http://stackoverflow.com/questions/3432830/list-comprehension-for-running-total Nếu bạn trích xuất đó, sau đó nó tốt, mặc dù tôi vẫn thích mã ban đầu. –

6

Bạn có thể viết cho mình một chức năng máy phát tích lũy. Sử dụng send để gửi giá trị vào trình tạo và nhận tổng mới.

def accumulator(n=0): 
    while True: 
     n += yield n 

acc = accumulator(0) 
acc.send(None) 

res = [{'value': acc.send(element['value']), 'date': element['date']} for element in some_data] 

Kết quả là, res

[{'value': 2, 'date': '2016-02-06'}, 
{'value': 3, 'date': '2016-02-07'}, 
{'value': 8, 'date': '2016-02-08'}, 
{'value': 11, 'date': '2016-02-09'}, 
{'value': 12, 'date': '2016-02-10'}] 
+1

Điều này là tuyệt vời :-) vì vậy +1 cho rằng ... Tuy nhiên, tôi nghĩ rằng đơn giản cho vòng lặp là đáng kể dễ đọc hơn. –

1

Dưới đây là một lót chạy trong thời gian tuyến tính:

reduce(lambda (c,s), a: (c + [{'value':s+a['value'], 'date':a['date']}], s+a['value']), some_data,([],0))[0] 

>>> [{'date': '2016-02-06', 'value': 2}, 
    {'date': '2016-02-07', 'value': 3}, 
    {'date': '2016-02-08', 'value': 8}, 
    {'date': '2016-02-09', 'value': 11}, 
    {'date': '2016-02-10', 'value': 12}] 

Bạn nên nhìn vào other running total question cho một phiên bản đơn giản hơn của cùng một vấn đề .

Các vấn đề liên quan