C'est assez différent de ce que j'ai trouvé dans de nombreux threads - je ne veux pas rendre la liste plate mais les niveaux non imbriqués comme suit:
[[[3, 3]]]
devrait être [3, 3]
[[[3, 4], [3, 3]]]
doit être [[3, 4], [3, 3]]
mais pas [3, 4], [3, 3]
ni [3, 4, 3, 3]
car cela change complètement la structure.
Fondamentalement, je voulais réduire les niveaux pour obtenir le même len (a_list)
dans la première et la deuxième itération avant la rupture de boucle. Mais mon idée est quelque peu fausse:
Ce code fonctionne pour tout sauf [[3], [4]]
. Je ne sais pas ce qui ne va pas aujourd'hui parce que cela a fonctionné hier. Besoin d'aide pour corriger cette fonction. Maintenant, il renvoie [3] mais devrait rester inchangé.
# Unlevel list - reduce unnecessary nesting without changing nested lists structure def unlevelList(l): if len(l) > 0 and isinstance(l, list): done = True while done == True: if isinstance(l[0], list): if len(l) == len(l[0]): l = l[0] else: l = l[0] done = False else: done = False return l else: return l
3 Réponses :
Je serais enclin à le faire avec la récursivité: si l'objet est une liste de longueur 1, enlevez le calque extérieur; puis, annulez récursivement le niveau de tous ses enfants.
When [[[3, 3]]] is unleveled, it becomes [3, 3] When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]] When [[3], [4]] is unleveled, it becomes [[3], [4]] When [[[3]]] is unleveled, it becomes 3 When [[[3], [3, 3]]] is unleveled, it becomes [[3], [3, 3]]
Résultat:
def unlevel(obj): while isinstance(obj, list) and len(obj) == 1: obj = obj[0] return obj test_cases = [ [[[3, 3]]], [[[3, 4], [3, 3]]], [[3], [4]], [[[3]]], [[[3], [3, 3]]] ] for x in test_cases: print("When {} is unleveled, it becomes {}".format(x, unlevel(x)))
Edit: relisant votre question, je pense peut-être vous voulez que [[3], [4]]
reste [[3], [4]]
. Si tel est le cas, alors j'interprète les exigences comme étant "seulement enlever les crochets excédentaires de la couche supérieure; laisser les listes intérieures à un élément inchangées". Dans ce cas, vous n'avez pas besoin de récursivité. Supprimez simplement la liste du haut jusqu'à ce que vous n'en puissiez plus, puis renvoyez-la.
When [[[3, 3]]] is unleveled, it becomes [3, 3] When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]] When [[3], [4]] is unleveled, it becomes [3, 4] When [[[3]]] is unleveled, it becomes 3 When [[[3], [3, 3]]] is unleveled, it becomes [3, [3, 3]]
Résultat:
def unlevel(obj): while isinstance(obj, list) and len(obj) == 1: obj = obj[0] if isinstance(obj, list): return [unlevel(item) for item in obj] else: return obj test_cases = [ [[[3, 3]]], [[[3, 4], [3, 3]]], [[3], [4]], [[[3]]], [[[3], [3, 3]]] ] for x in test_cases: print("When {} is unleveled, it becomes {}".format(x, unlevel(x)))
p >
Cela redéfinit incorrectement [[[3], [3, 3]]]
en [3, [3, 3]]
, où je crois [[3 ], [3, 3]]
est attendu.
@blhsing Je pense que vous avez raison. J'ai ajouté une approche supplémentaire.
Honnêtement pas mal. Ce "supports excédentaires uniquement" était ce que je recherchais. Merci pour 2 versions.
Ceci est fait mais je ne peux pas changer [[[[4]]]]
pour obtenir une liste toujours. Donc, à la place, 4
veut avoir [4]
.
Hmm, vous pourriez peut-être changer la dernière ligne en return obj if isinstance (obj, list) else [obj]
. La réponse de Nathan garantit également que le résultat est une liste.
Je recommande également une solution récursive
[[3], [3, 3]] [3, 3] [[3, 4], [3, 3]] [[3], [4]] [3]
Certains cas de test
test_cases = [ [[[3], [3, 3]]], [[[3, 3]]], [[[3, 4], [3, 3]]], [[3], [4]], [[[3]]] ] for i in test_cases: print(unnest(i))
donne
def unnest(l): if isinstance(l, list) and len(l) == 1 and isinstance(l[0], list): return unnest(l[0]) return l
Ce code semble faire exactement ce que vous voulez. Conservez les listes sous forme de listes (mais plates).
import itertools a = [[[[1, 2]]], [[2, 3, 4, 5]], [[[[[[134, 56]]]]]], 9, 8, 0] res = [] for element in a: if isinstance(element, list): while len(element) == 1: element = list(itertools.chain(*element)) res.append(element) else: res.append(element) print(res)
Avec le résultat res
étant [[1, 2], [2, 3, 4, 5], [134, 56], 9, 8, 0]
Pas exactement ce que je cherchais (ne pas enlever les nids internes) mais c'est utile aussi.
Je pense que votre implémentation rencontrera des problèmes si vos sous-listes sont de tailles différentes, c'est-à-dire si votre structure de données n'est pas rectangulaire.