Python >> Tutoriel Python >  >> Python

Comment diviser une liste en morceaux pairs en Python

Introduction

Le fractionnement de chaînes et de listes est une activité de programmation courante en Python et dans d'autres langages. Parfois, nous devons diviser nos données de manière particulière, mais le plus souvent - en morceaux égaux.

Le langage n'a pas de fonction intégrée pour le faire et dans ce tutoriel, nous verrons comment diviser une liste en morceaux pairs en Python .

Dans la plupart des cas, vous pouvez vous en sortir en utilisant des générateurs :

def chunk_using_generators(lst, n):
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

Cependant, il existe d'autres façons intéressantes de le faire, chacune avec ses avantages et ses inconvénients !

Diviser une liste en morceaux pairs de N éléments

Une liste peut être divisée en fonction de la taille du bloc défini. Cela signifie que nous pouvons définir la taille du morceau. Si le sous-ensemble de la liste ne rentre pas dans la taille du morceau défini, des charges doivent être insérées à la place des supports d'éléments vides. Nous utiliserons None dans ces cas.

Créons un nouveau fichier nommé chunk_based_on_size.py et ajoutez le contenu suivant :

def chunk_based_on_size(lst, n):
    for x in range(0, len(lst), n):
        each_chunk = lst[x: n+x]

        if len(each_chunk) < n:
            each_chunk = each_chunk + [None for y in range(n-len(each_chunk))]
        yield each_chunk

print(list(chunk_based_on_size([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 7)))

Le chunk_based_on_size() ci-dessus la fonction prend les arguments :lst pour la liste et chunk_size pour un nombre pour le diviser par. La fonction parcourt la liste avec un incrément de la taille du bloc n . On s'attend à ce que chaque bloc ait la taille donnée en argument. S'il n'y a pas assez d'éléments pour faire une division de la même taille, les éléments inutilisés restants sont remplis avec None .

L'exécution de ce script renvoie la liste de listes suivante :

$ python3 chunk_based_on_size.py
[[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, None]]

La liste a été divisée en morceaux égaux de 7 éléments chacun.

Python a des utilitaires pour simplifier ce processus. Nous pouvons utiliser le zip_longest fonction de itertools pour simplifier la fonction précédente. Créons un nouveau fichier chunk_using_itertools.py et ajoutez le code suivant :

from itertools import zip_longest

def chunk_using_itertools(lst):
    iter_ = iter(lst)
    return list(zip_longest(iter_, iter_, iter_, iter_, iter_, iter_, iter_))

print(chunk_using_itertools([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]))

Ce code itère les éléments et renvoie un morceau de la longueur souhaitée - en fonction des arguments que vous fournissez. Nous avons mis 7 iter_ arguments ici. Le zip_longest() La fonction agrège et renvoie les éléments de chaque itérable. Dans ce cas, il regrouperait les éléments de la liste itérée 7 fois en une seule fois. Cela crée alors de nombreux itérateurs contenant 7 éléments séquentiels, qui sont ensuite convertis en liste et renvoyés.

Lorsque vous exécutez cet extrait, cela donne :

$ python3 chunk_using_itertools.py
[[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, None]]

Cette fonction plus courte produit la même entrée. Cependant, c'est beaucoup plus limité car nous devons écrire manuellement le nombre d'éléments que nous voulons dans le code, et c'est un peu gênant de simplement mettre un tas de iter_ s dans le zip_longest() appeler.

La meilleure solution serait d'utiliser des générateurs. Créons un nouveau fichier, chunk_using_generators.py :

def chunk_using_generators(lst, n):
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

print(list(chunk_using_generators([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 7)))

Ce générateur donne une sous-liste contenant n éléments. À la fin, cela aurait donné une sous-liste pour chaque morceau. L'exécution de ce code produit cette sortie :

$ python3 chunk_using_generators.py
[[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13]]

Cette solution fonctionne mieux si vous n'avez pas besoin de rembourrage avec None ou autrement.

Diviser une liste en N morceaux pairs

Dans la section précédente, nous avons divisé la liste en fonction de la taille des morceaux individuels afin que chaque morceau ait le même nombre d'éléments. Il y a une autre façon d'interpréter ce problème. Que faisons-nous lorsque nous voulons diviser une liste non pas en fonction du nombre d'éléments dans chaque bloc, mais en fonction du nombre de blocs que nous voulons créer ?

Par exemple, au lieu de diviser une liste en morceaux où chaque morceau a 7 éléments, nous voulons diviser une liste en 7 morceaux pairs. Dans ce cas, nous ne connaissons peut-être pas la taille de chaque morceau.

La logique est similaire aux solutions précédentes, cependant, la taille du morceau est la valeur plafond de la longueur de la liste divisée par le nombre de morceaux requis. Semblable aux exemples de code précédents, si un morceau a des emplacements vacants, ceux-ci seront remplis par la valeur de remplissage None :

import math

def chunk_based_on_number(lst, chunk_numbers):
    n = math.ceil(len(lst)/chunk_numbers)

    for x in range(0, len(lst), n):
        each_chunk = lst[x: n+x]

        if len(each_chunk) < n:
            each_chunk = each_chunk + [None for y in range(n-len(each_chunk))]
        yield each_chunk

print(list(chunk_based_on_number([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], chunk_numbers=7)))

Nous déterminons le nombre de listes dont nous avons besoin pour créer et stocker cette valeur dans n . Nous créons ensuite une sous-liste pour les deux éléments à la fois, en remplissant la sortie au cas où la taille de notre bloc serait inférieure à la longueur souhaitée.

Lorsque nous exécutons ce fichier, nous verrons :

$ python3 chunk_based_on_number.py
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, None]]

Comme on le voit dans la sortie ci-dessus, la liste a été divisée en 7 listes individuelles de tailles égales, basées sur l'argument chunk_numbers fourni.

Conclusion

Dans cet article, nous avons vu quelques-unes des façons dont une liste peut être divisée en morceaux et listes de taille égale basés sur des méthodes personnalisées et en utilisant les modules intégrés.

Les solutions mentionnées dans ce didacticiel ne se limitent pas à celles définies ici, mais il existe de nombreuses autres façons créatives de diviser votre liste en morceaux pairs également.