2011-01-25 49 views
5

thể trùng lặp:
List comprehension for running totalPython danh sách hiểu

Tôi đang cố gắng để viết một tuyên bố danh sách hiểu ngắn gọn để tạo ra một lũy: Ví dụ:

print f([0.2, 0.3,0.1,0.4]) 
[0.2,0.5,0.6,1.0] 

Một thủ tục tiêu chuẩn sẽ giống như thế này (Tôi muốn viết một danh sách hiểu cho lần thứ e function f()):

def f(probabilities) : 

    sum = 0 
    returnList = [] 
    for count in probabilities: 
     sum +=count 
     returnList = returnList + [sum] 
    return returnList 

Chỉnh sửa: Tôi tìm thấy hàm numpy.cumsum(). Tôi sẽ kiểm tra xem nó có sử dụng tính năng hiểu danh sách hay không.

+0

Câu hỏi là gì? – Elalfer

+0

@Elalfer - Có vẻ như anh ta muốn viết một sự hiểu biết danh sách mà hành vi của nó giống hệt với hàm 'f()' của anh ta. –

+0

Đó là chính xác. Tệ của tôi, tôi nên rõ ràng hơn. – GeneralBecos

Trả lời

8

Hoạt động đó phổ biến đến mức nhiều ngôn ngữ (chủ yếu là chức năng, nhưng không chỉ) cung cấp trừu tượng cho nó, thường với tên scanl (giống như reduce với kết quả trung gian). Hãy gọi nó là ireduce ("lặp đi lặp lại giảm"):

def ireduce(f, state, it): 
    for x in it: 
     state = f(state, x) 
     yield state 

Và bây giờ sử dụng nó:

import operator 

def f(probabilities): 
    return ireduce(operator.add, 0, probabilities) 

print(list(f([0.2, 0.3,0.1,0.4]))) 
# [0.2, 0.5, 0.6, 1.0] 
+0

Đây là một điều tốt để có trong hộp công cụ của một người; nhưng chắc chắn chúng ta có thể nghĩ ra một tên Pythonic hơn là sao chép những gì các ngôn ngữ khác gọi nó? FWIW, C++ gọi lệnh này là 'std :: partial_sum' và sử dụng phần bổ sung làm hoạt động theo mặc định. –

+0

@Karl. Một số người gọi nó là ireduce, tôi thích nó. "partial_sum" là một tên tốt khi thêm nhưng với các hoạt động khác có vẻ hơi gây hiểu nhầm. – tokland

8
[sum(probabilities[:i+1]) for i in range(len(probabilities))] 

Nhưng đừng làm vậy vì đó là O (n^2). Việc hiểu danh sách Python không được thiết kế cho việc này. Sử dụng mã thủ tục mà bạn đã viết.

+0

Bây giờ đó là một danh sách tuyệt vời hiểu. – user225312

1

Nó không thực sự xinh đẹp, và nó không sử dụng comprehensions danh sách, nhưng bạn có thể làm điều này với giảm() chức năng, trong đó giá trị tích lũy là một bộ lưu giữ tổng hiện tại và danh sách kết quả:

a = [0.2, 0.3, 0.1, 0.4] 
reduce((lambda result, val: (result[0] + val, result[1] + [result[0] + val])), a, (0, []))[1] 

Sự thiếu hỗ trợ của Python đối với nhiều dòng lambda làm cho loại xấu xí này. Sử dụng chức năng riêng biệt sẽ tốt hơn:

a = [0.2, 0.3, 0.1, 0.4] 
    def accumulate(result, val): 
     return (result[0] + val, result[1] + [result[0] + val]) 

    reduce(accumulate, a, (0, []))[1] 
Các vấn đề liên quan