Welcome to MMA SE! The reason is that And
(&&
) is short-circuited. This means that as soon as an argument is False
(starting from the left), the whole thing immediately evaluates to False
. So False && expr
is False
for any expr
.
The opposite behavior occurs when the first argument is True
: True && expr
gives expr
for any expr
. If the first argument is True
, then you still need to check the next arguments. But you know that whatever the output of And
is, it will be given by those next arguments; so you can disregard the initial True
. And from the docs:
And
gives symbolic results when necessary, removing initial arguments that are True
.
So &&
is not actually preserving the list structure in the first case; it's just returning the second argument.
To preserve the list structure, one solution is to use Map
to map a function over a list, for which there is the syntactic sugar /@
. We can map the anonymous functions True && # &
and False && # &
over the list:
True && # & /@ {False, True}
False && # & /@ {False, True}
However, depending on your application, you might want to do things slightly differently. Defining a symbol to "mean" And
but have the attribute Listable
comes to mind, for example (since the attribute gets applied before the definition does):
myAnd[args___] := And[args]
SetAttributes[myAnd, Listable]
myAnd[True, {False, True}]
myAnd[False, {False, True}]
The Help docs for Function
and Map
likely link to other things you might find useful at the bottom!
Map
ping (or/@
)True
orFalse
over a list of Boolean values while preserving list structure would be done like this. $\endgroup$