You could use io.StringIO to feed a string into read_csv:
In [23]: pd.read_csv(io.StringIO('\n'.join(list_vals)), delim_whitespace=True)
Out[23]:
col_a col_B col_C
0 12.0 34.0 10.0
1 15.0 111.0 23.0
This has the advantage that it automatically does the type interpretation that pandas would do if you were reading an ordinary csv-- the columns are floats:
In [24]: _.dtypes
Out[24]:
col_a float64
col_B float64
col_C float64
dtype: object
While you could just feed your list into the DataFrame constructor directly, everything would stay strings:
In [21]: pd.DataFrame(columns=list_vals[0].split(),
data=[row.split() for row in list_vals[1:]])
Out[21]:
col_a col_B col_C
0 12.0 34.0 10.0
1 15.0 111.0 23
In [22]: _.dtypes
Out[22]:
col_a object
col_B object
col_C object
dtype: object
We could add dtype=float to fix this, of course, but we might have mixed types, which the read_csv approach would handle in the usual way and here we'd have to do manually.