Edited:  What I described below under Previous is chained indexing and may not work in some situations.  The best practice is to use loc, but the concept is the same:
df.loc[row, col]
row and col can be specified directly (e.g., 'A' or ['A', 'B']) or with a mask (e.g. df['B'] == 3).  Using the example below:
df.loc[df['B'] == 3, 'A']
Previous:  It's easier for me to think in these terms, but borrowing from other answers.  The value you want is located in a dataframe:
df[*column*][*row*]
where column and row point to the values you want returned.  For your example, column is 'A' and for row you use a mask:
df['B'] == 3
To get the first matched value from the series there are several options:
df['A'][df['B'] == 3].values[0]
df['A'][df['B'] == 3].iloc[0]
df['A'][df['B'] == 3].to_numpy()[0]