This reads the argument as a list of items, with ^ and _ as item delimiters (parsing separators). If either/both are present, the list length will exceed one. I then use the list length to decide whether or not to add parens.
\documentclass{article}
\usepackage{listofitems}
\newcommand\transpose[1]{%
\setsepchar{_||^}%
\readlist\mymat{#1}%
\ifnum\mymatlen>1\left(#1\right)^T\else#1^T\fi%
}
\begin{document}
\[
\transpose{D}
\]
\[
\transpose{D_1}
\]
\[
\transpose{D^x}
\]
\end{document}

A single expansion upon the argument, in the form of
\newcommand\transpose[1]{%
\setsepchar{_||^}%
\expandafter\readlist\expandafter\mymat\expandafter{#1}%
\ifnum\mymatlen>1\left(#1\right)^T\else#1^T\fi%
}
would allow some embedded cases to be properly digested, for example,
\def\myvar{A_x}
\[
\transpose{\myvar}
\]

#1merely expands to something with such sub/superscripts? – Andrew Swann Oct 06 '17 at 11:34