Can I split this column containing a mix of tuples/None more efficiently?

Here is another way (comments inline):

c=df.tuples.astype(bool) #similar to df.tuples.notnull()
#create a dataframe by dropping the None and assign index as df.index where c is True
d=pd.DataFrame(df.tuples.dropna().values.tolist(),columns=list('xy'),index=df[c].index)
final=pd.concat([df,d],axis=1) #concat them both

  id  tuples    x    y
0  a    None  NaN  NaN
1  b  (1, 2)  1.0  2.0
2  c    None  NaN  NaN
3  d  (3, 4)  3.0  4.0

df[get_rows] is a copy, set value to df[get_rows][['x','y']] does not change the underlying data. Just use df[['x','y']] to create now columns.

df = pd.DataFrame({'id':list('abcd')})

df['tuples'] = df.index.map(lambda i:(i,i+1) if i%2 else None)

get_rows = df.tuples.notnull()

df[['x','y']] = df[get_rows].apply(lambda x:x.tuples,result_type='expand',axis=1)

print(df)

  id  tuples    x    y
0  a    None  NaN  NaN
1  b  (1, 2)  1.0  2.0
2  c    None  NaN  NaN
3  d  (3, 4)  3.0  4.0