Assume $d_i$ is an increasing strictly-positive sequence so that there is always a local minima for your function between $-1/d_i$ and $-1/d_{i+1}$. Since $f^{\prime\prime}(\lambda)\ge0$, these local minima are unique. Finding this local minima can always be handled using bracketing methods applied to $f^\prime(\lambda)$, which in your case is
$$f^\prime(\lambda)=\sum_i\frac{-2d_ic_i^2}{(1+\lambda d_i)^3}.$$
Let $\lambda_i\in(-1/d_i,-1/d_{i+1})$ be these minimas. If $f(\lambda_i)=0$, then that is the only root in $(-1/d_i,-1/d_{i+1})$. Otherwise if $f(\lambda_i)<0$, then only roots exist and are between $-1/d_i$ and $\lambda_i$, and $\lambda_i$ and $-1/d_{i+1}$, which can again be found using bracketing methods.
This covers all roots between the $-1/d_i$, leaving only $\lambda\to\pm\infty$ cases to be explored. Since $f(\lambda)\to-1$ as $\lambda\to\pm\infty$, we know 2 more roots are guaranteed to exist in $(-\infty,-1/d_0)\cup(-1/d_n,\infty)$, which can again be found using bracketing methods. Furthermore, $f^\prime(\lambda)\ne0$ in that region, which guarantees no other roots exist in those regions.
Similar cases may be constructed if $d_i$ have both positive and negative signs but is a bit messier.
Some example code implementing the above algorithm.