If need get first non None value per rows after key column use DataFrame.set_index with replace possible None strings with back filling missing values and selected first column by position, last use Series.reset_index:
df = (df.set_index('key')
.replace('None', np.nan)
.bfill(axis=1)
.iloc[:, 0]
.reset_index(name='letter')))
print (df)
key letter
0 1 NaN
1 2 a
2 3 b
3 4 c
4 5 c
If possible multiple non None value per rows use:
d = {'key': [1,2,3,4,5],
'a': ['None','a', 'None','None','None'],
'b': ['None','b','b','None','None'],
'c':['None','None','None','c','c']}
df = pd.DataFrame(d)
df = (df[['key']].join(df.set_index('key')
.replace('None', np.nan)
.stack()
.groupby(level=0)
.agg(','.join)
.rename('letter'), on='key'))
print (df)
key letter
0 1 NaN
1 2 a,b
2 3 b
3 4 c
4 5 c
Or:
df = (df.set_index('key')
.replace('None', np.nan)
.apply(lambda x: ','.join(x.dropna()), axis=1)
.replace('', np.nan)
.reset_index(name='letter'))
print (df)
key letter
0 1 NaN
1 2 a,b
2 3 b
3 4 c
4 5 c