Question

def flattenList(toFlatten):
 final=[]
 for el in toFlatten:
  if isinstance(el, list):
   final.extend(flattenList(el))
  else:
   final.append(el)
 return final

Quand je ne sais pas à quel point les listes nid, c'est la seule façon que je peux penser à le faire.

Était-ce utile?

La solution

est ici une autre option (même si il peut y avoir quelque chose de plus propre que type de vérification, comme le test si quelque chose est itérable et donc pas un « atome »):

def flatten(lst):
    if not isinstance(lst,list):
        return [lst]
    else:
        return reduce(lambda x,y:x+y,[flatten(x) for x in lst],[])

Il est basé sur le schéma semblable à quelque chose.

Autres conseils

  1. Vous devez éviter en Python typage. Dans ce cas, cela signifie éviter les structures arbitrairement imbriquées où vous distinguez par type. Vous pouvez construire votre propre type de nœud que vous pouvez parcourir par des méthodes autre que la vérification du type, comme regarder un attribut spécifique.

  2. Pour aplatir un niveau ou exactement n niveaux, regardez itertools.chain.from_iterable.

  3. Je ne sais pas ce que vous entendez par « fonctionnelle ». Ce code est assez fonctionnel: il utilise la récursivité (pas son crédit!) Et il ne mute pas son argument. (Au sens strict, il utilise l'état mutable pour la construction d'une liste, mais qui est juste la façon dont vous le faites en Python.

  4. Je suppose que l'un plus attribut fonctionnel serait l'évaluation paresseuse. Vous pouvez mettre en œuvre cette thusly

    def flatten(toFlatten):
        for item in toFlatten:
            if isinstance(item, list): # Ewww, typchecking
                for subitem in flatten(item): # they are considering adding 
                    yield subitem             # "yield from" to the  language
                                              # to give this pattern syntax
            else:
                yield item
    
  5. La récursion est très limitée en Python (au moins, dans toutes ses grandes implémentations) et doit généralement être évitée pour la profondeur arbitraire. Il est tout à fait possible de réécrire ce (et tout le code récursif) à utiliser itération, qui en font plus évolutive (et moins fonctionnelle, ce qui est une bonne chose en Python, ce qui est pas particulièrement adapté pour FP.)

Cette réponse explique pourquoi vous ne voulez pas utiliser reduce pour cela en Python.

Considérons l'extrait

reduce(operator.add, [[1], [2], [3], [4], [5]])

Qu'est-ce que cela a à faire?

[1] + [2] => [1, 2]
[1, 2] + [3] => This makes a new list, having to go over 1, then 2, then 3. [1, 2, 3]
[1, 2, 3] + [4] => This has to copy the 1, 2, and 3 and then put 4 in the new list
[1, 2, 3, 4] + [5] => The length of stuff I have to copy gets bigger each time!

Ce comportement quadratique est complètement évitée: la solution originale (et un nombre quelconque d'autres solutions) ne forme pas ces étapes de copie intermédiaire

.

Dans la doc itertools , il y a une fonction flatten()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top