Estoy haciendo un juego de acorazados, y este código comprueba cuántos barcos quedan. Solo sé que se puede hacer más fácil con for loops, pero por alguna razón no puedo entenderlo. Este es el código:

#empty Dictonary. This Dict will store the coords of the ship
boatDict = {'destroyer1': [], 'destroyer2': [],
            'submarine1': [], 'submarine2': [],
            'battleship': [], 'carrier': []}

if boatDict['destroyer1'] == []:
    destroyer = 2
elif boatDict['destroyer1'] != []:
    destroyer = 1
elif boatDict['destroyer2'] != []:
    destroyer = 0

if boatDict['submarine1'] == []:
    submarine = 2
elif boatDict['submarine1'] != []:
    submarine = 1
elif boatDict['submarine2'] != []:
    submarine = 0

if boatDict['battleship'] == []:
    battleship = 1
elif boatDict['battleship'] != []:
    battleship = 0

if boatDict['carrier'] == []:
    carrier = 1
elif boatDict['carrier'] != []:
    carrier = 0

¡Gracias de antemano!

EDITAR: aclara la pregunta y el código

1
ThomasNL 30 oct. 2017 a las 23:14

3 respuestas

La mejor respuesta

Como valor booleano, una lista vacía es falsa y una lista no vacía es verdadera. Además, los valores booleanos True y False son realmente solo los enteros 1 y 0 disfrazados. Como resultado, simplemente puedes escribir

destroyers = sum(bool(boatDict[x]) for x in 'destroyer1', 'destroyer2')
submarines = sum(bool(boatDict[x]) for x in 'submarine1', 'submarine2')

battleships = int(bool(boatDict['battleship']))
carrier = int(bool(boatDict['carrier']))
1
chepner 30 oct. 2017 a las 22:27

Suponiendo que boatList es un diccionario, puede obtener cuántos destructores han sido eliminados :

destroyersEliminated = 0
for k, v in boatList.items(): #in py2, use iteritems()
    if k in ["destroyer1", "destroyer2"] and v != []:
        destroyersEliminated += 1

Entonces puedes restar eso del número total de destructores:

destroyers = totalDestroyers = destroyersEliminated

También puede optar por hacer esto con una lista de comprensión:

destroyersEliminated = len(k for k in boatList 
    if k in ["destroyer1", "destroyer2"]
    and boatList[k] != [])

Nota al margen: hay muchas maneras de hacer este limpiador, incluyendo un enfoque orientado a objetos donde cada barco es un objeto con un tipo y un estado; entonces podrá recorrer una lista de ellos y verificar su tipo y estado para obtener recuentos.

0
CPoll 30 oct. 2017 a las 20:38

Crearía un diccionario de recuento de barcos, como este:

boatDict = {'destroyer1': [3, 5], 'destroyer2': [7, 2],
            'submarine1': [1, 1], 'submarine2': [],
            'battleship': [], 'carrier': [5, 2]}

boatCount = {}

for key in boatDict:
    if boatDict[key] != []:
        boat = ''.join(i for i in str(key) if not i.isdigit())
        if boat not in boatCount:
            boatCount[boat] = 1
        else:
            boatCount[boat] += 1

print(boatCount)

#output

{'submarine': 1, 'carrier': 1, 'destroyer': 2}

Así que crea un diccionario vacío, cuenta barco. Luego recorra el barco dict y para cada clave que no esté asociada con una lista vacía, cree una variable llamada barco. La variable del barco se utilizará como clave para el diccionario de recuento de barcos. También elimina los números de las teclas como destroyer1 y destroyer2, porque en el nuevo diccionario, estos deberían combinarse y simplemente llamarse destructor.

La siguiente instrucción if verifica si la nueva variable de barco existe en el recuento de barcos. Si no lo hace, crea una nueva clave y establece el recuento de esa clave en uno. Si la clave ya existe, la instrucción else agrega uno al recuento de esa clave.

Actualización para mostrar 0 para barcos que han sido destruidos:

boatDict = {'destroyer1': [3, 5], 'destroyer2': [7, 2],
            'submarine1': [1, 1], 'submarine2': [],
            'battleship': [], 'carrier': [5, 2]}

boatCount = {}

for key in boatDict:
    boat = ''.join(i for i in str(key) if not i.isdigit())
    if boat in boatCount:
        if boatDict[key] != []:
            boatCount[boat] += 1
    else:
        if boatDict[key] != []:
            boatCount[boat] = 1
        else:
            boatCount[boat] = 0

print(boatCount)

#output

{'destroyer': 2, 'battleship': 0, 'submarine': 1, 'carrier': 1}
2
kjmerf 30 oct. 2017 a las 22:12