Not that I know of, at least when the probabilities are not all equal. Higher order iteration libraries like Python's Itertools allow you to iterate over combinations like you've described, and you might have access to such a library depending on your programming language. You can also do the operation recursively as follows. Let T(n, s) be the probability of precisely s successes in events at index n or higher. Here, for instance, D has index 3 (starting from 0) so T(3, 1) = Pr(D)*(1-Pr(E)) + (1-Pr(D))*Pr(E) = 0.2*0.9 + 0.8*0.1 = 0.26. In general,
T(n, s) = Pr(n) * T(n+1, s-1) + (1-Pr(n)) * T(n+1, s),
where in the base cases,
T(n, 0) = 1 if n is out of range
T(n, -1) = 0 if n is out of range
Again in Python, this is...
and some example output is
def T(n, s):
return 1 if s==0 else 0
return P[n] * T(n+1, s-1) + (1-P[n])* T(n+1, s)
Note that this code works very poorly for remotely large lists since it doubles the number of calls at each step--but I don't know any algorithm that would work particularly well in the general case anyway.
>>> P = [0.5, 0.4, 0.3, 0.2, 0.1]
>>> T(3, 1)
>>> T(0, 3)