2012-04-09 31 views
5

Define un procedimiento, same_structure, que toma dos entradas. Debe mostrar True si las listas tienen la misma estructura, y False de lo contrario. Dos valores, p y q tienen la misma estructura si:¿Cómo encontrar dos listas con la misma estructura en python?

Neither p or q is a list. 

Both p and q are lists, they have the same number of elements, and each 
element of p has the same structure as the corresponding element of q. 

EDIT: Para hacer que la imagen clara los siguientes son los resultados esperados

same_structure([1, 0, 1], [2, 1, 2]) 
    ---> True 
same_structure([1, [0], 1], [2, 5, 3]) 
    ---> False 
same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['d', 'e']]]]) 
    ---> True 
same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['de']]]]) 
    ---> False 

pensé recursividad sería mejor para solucionar este problema en Python he encontrado el siguiente código pero no funciona.

def is_list(p): 
    return isinstance(p, list) 

def same_structure(a,b): 
    if not is_list(a) and not is_list(b): 
     return True 
    elif is_list(a) and is_list(b): 
     if len(a) == len(b): 
      same_structure(a[1:],b[1:]) 
    else: 
     return False 
+0

@SvenMarnach: a menos que esté leyendo mal la pregunta, [2, (3,4)] y [2, (5,)] tienen la misma estructura: son ambas listas, que tienen la misma número de elementos, y cada elemento de p tiene la misma estructura que el elemento correspondiente de q porque ninguno es una lista. IOW solo importa la estructura de la lista, los valores no (de modo que [2] y [3] también tienen la misma estructura). – DSM

+1

Defina "misma estructura" para una lista que para python ['a', '1 '] no es igual a [' 1 ',' a ']. Tal vez sería mejor usar sets también. – KurzedMetal

+0

En este contexto, aunque creo que * * diría que contienen los mismos elementos, donde la igualdad se define por la relación dada. Creo que tuve una pregunta como esta, en el día. – DSM

Respuesta

3

recursividad sería una buena idea, pero no la forma en que has sugerido. En primer lugar (y esto puede ser sólo un error tipográfico), que en realidad no vuelva cualquier cosa aquí:

if len(a) == len(b): 
    same_structure(a[1:],b[1:]) 

En segundo lugar, usted debe tratar de forma recursiva con cada elemento, no cada sublista. es decir .:

if len(a) == len(b): 
    for i in range(len(a)): 
     if not same_structure(a[i], b[i]): 
      return False 
    return True 
else: 
    return False 

Espero que esto ayude.

5

Falta un caso y olvida volver en el segundo caso. Observe que no es necesario comparar explícitamente las longitudes de las listas, ya que el primer caso se ocupa de esto: si una de las listas está vacía y la otra no, es porque una lista tenía menos elementos que la otra:

def same_structure(a, b): 
    if a == [] or b == []: # one of the lists is empty 
     return a == b  # are both of the lists empty? 
    elif is_list(a[0]) != is_list(b[0]): 
     return False  # one of the elements is a list and the other is not 
    elif not is_list(a[0]): # neither element is a list 
     return same_structure(a[1:], b[1:]) 
    else:     # both elements are lists 
     return same_structure(a[0], b[0]) and same_structure(a[1:], b[1:]) 
+0

Gracias por la respuesta, pero no funciona debido a la comparación entera en la segunda condición – u449355

+0

Por favor, vea la salida esperada en cuestión, lo entenderá. – u449355

+0

@UmeshKacha la segunda condición?, Mencionan esto: 'is_list (a [0])! = Is_list (b [0])'. Esa no es una comparación entera, es una comparación booleana.Lo que dice esa línea es: "si uno de los elementos es una lista y el otro no es una lista, entonces devuelve False, porque la estructura es diferente" –

5

en lugar de same_structure(a[1:],b[1:]), es necesario comprobar par de elementos de a y B uno por uno

def is_list(p): 
    return isinstance(p, list) 

def same_structure(a, b): 
    if not is_list(a) and not is_list(b): 
     return True 
    elif (is_list(a) and is_list(b)) and (len(a) == len(b)): 
     return all(map(same_structure, a, b)) # Here 
    return False 
1

Dado que la especificación dice que la entrada son dos listas, puede recorrer las listas dentro de su función sin más comprueba, y solo hace llamadas recursivas si encuentra sublistas:

def same_structure(a, b): 
    if len(a) != len(b): 
     return False 
    return all(is_list(x) and is_list(y) and same_structure(x, y) or 
       not is_list(x) and not is_list(y) 
       for x, y in zip(a, b)) 
0

Usted puede tratar de esta manera también también, comprobar el tipo de ambas listas & longitud de ambas listas y hacer esto de forma recursiva para la sub-listas tanto de la lista.

def same_structure(a,b): 
    return isinstance(a, list) and isinstance(b, list) and len(a) == len(b) 
    and all(same_structure_as(c, d) for c, d in zip(a, b) if isinstance(c, list)) 
+0

Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a cómo y/o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta. –

Cuestiones relacionadas