As oskros mentioned in the comments you can just do n3[1:50].
In this answer I will try to explain why your other attempts don't work with examples.
import pandas as pd
# Example value of n3 for demo purposes
n3 = pd.DataFrame({"A": [1000 for _ in range(10000)]})
>>> n3.index
RangeIndex(start=0, stop=10000, step=1)
So n3.index in this example is a type of Pandas Index (RangeIndex) that starts at 0, stops at 10000 and increments with one every time.
The documentation says the following on pandas.Index.isin
Compute boolean array of whether each index value is found in the passed set of values. The length of the returned boolean array matches the length of the index.
So when you do this
>>> n3[n3.index.isin([1,50])]
A
1 1000
50 1000
You're actually saying something like: For each index value determine if it exists in the set passed as an input to isin. Since you're passing [1,50] this matches the index where the index is 1 or where it is 50. Two numbers that match the index values means you are left with two rows after filtering n3.
The other examples listed in your question using iloc do about the same.
n3[1:50]