Não necessariamente. Se vc tiver A, B e C, e quiser fazer um A and B and C, daria também: seria o mesmo que fazer A and B, e depois pegar o resultado e fazer outro and com C.
A ideia básica seria (se for isso mesmo que vc quer fazer):
def PortaAND(valores):
if len(valores) == 0: # se está vazio, é falso
return 0
res = valores[0] # pega o primeiro
for i in valores[1:]: # faz o loop do segundo em diante
if res == 1:
res = i
return res
Claro, assumindo que a lista só vai ter zeros e uns (não estou validando nada disso). A ideia de um AND é: se um elemento é 1, o resultado será 1 se o próximo também for 1, e zero se o próximo também for zero. Ou seja, se o elemento atual é 1, o resultado é o próximo elemento (é isso que esse if faz). Se o atual não for 1, é porque é zero, então o resultado será zero e por isso eu não preciso mudá-lo.
A ideia do OR é similar:
def PortaOR(valores):
if len(valores) == 0: # se está vazio, é falso
return 0
res = valores[0]
for i in valores[1:]:
if res == 0:
res = i
return res
E claro que dá pra otimizar mais. Por exemplo, no AND, se algum elemento for zero o resultado já é zero, aí nem preciso verificar o resto (já poderia retornar zero direto). No OR é similar, se algum for 1 o resultado já será 1. Ex:
def PortaAND(valores):
if len(valores) == 0: # se está vazio, é falso
return 0
for i in valores:
if i == 0: # se for zero, o resultado já é zero, nem precisa ver o resto
return 0
return 1