Calculating values of frequency bins in Python
This is simply how Discrete Fourier Transform (i.e. Fourier Transform theory applied on sampled signal) works.
You get an output of length N if your input has length N, and after removal of symmetric part, what you get are $\frac{N}{2}$ points that span frequencies 0 (DC component) to Nyquist frequency ($\frac{F_s}{2}$).

For this same reason, the more points your signal have (let's say for a fixed sampling rate $F_s$) the more resolved your FFT output is since the spacing between each frequency bin in the output is:
$$
\frac{F_s/2}{N/2} = \frac{F_s}{N}
$$



UPDATE:

Regardless of the sampling frequency the FFT returns $N$ data points for an input with $N$ samples. What we say is that all the points of the output spread the circle: $[0;2\pi]$ in radian/sample or sometimes denoted $[0;1]$ in cycles/sample (called the normalized frequency). All these bins correspond to how many cycles, or oscillations you might have between each samples. You can measure at best half a cycle between each sample (for real signals). This is usually converted back into frequency simply by knowing the sampling rate.

So indeed if your signal is longer, you will have a longer output. Now what I was pointing out is that if your signal is longer but recorded with same $F_s$, i.e. it actually last longer in time, then you will resolve smaller frequency (since you have more time in total, this gives finer information in the frequency domain). That is, the bins are closer to each other in frequency domain ($\Delta f = F_s/N = 1/T$ get smaller). So basically, the longer you record, for whatever sampling rate, the finer resolution you get in the frequency domain.

In summary, if you do not know $F_s$ the bins are located (after removal of symmetrical part):


span $[0,0.5]$, and spaced by $1/N$, and the unit is cycle/sample, OR
span $[0,\pi]$, spaced by $2\pi/N$, unit is radian/sample


Then if you know $F_s$, simply transform back into Hertz, knowing that it must span $[0, F_s/2]$.