Disons que j'ai un tableau Je cherche un moyen de diviser mon tableau en un tableau [0, 1, 2, 3, 4, 5, 6, 7] et un tuple: (3, 3, 2) . 3 basé sur mes données de tuple: [0, 1, 2]
[3, 4, 5]
[6, 7]
Je peux écrire un code simple comme celui-ci pour obtenir ce que je veux, mais je cherche une manière correcte et pythonique de faire ceci:
J'ai utilisé des listes pour plus de simplicité.
a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
pointer = 0
for i in b:
lst = a[pointer:pointer+i]
pointer += i
print(lst)
Ou celui-ci:
a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
pointer = 0
for i in b:
lst = []
for j in range(i):
lst.append(a[pointer])
pointer += 1
print(lst)
Résultats:
[0, 1, 2] [3, 4, 5] [6, 7]
5 Réponses :
Une manière plus simple est la suivante:
a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
for ind in b:
print(a[:ind])
a = a[ind:]
Il parcourt les tailles de tranche dans b tout en raccourcissant le tableau d'origine à chaque fois. Vous pouvez facilement ajouter les tranches résultantes en tant que sous-listes si vous en avez besoin pour autre chose. C'est presque comme l'une de vos solutions, sauf qu'elle n'utilise aucune variable supplémentaire et itère directement à travers des éléments de b .
De plus, je n'appellerais pas les variables a et b - sûrement pas dans ce cas où les variables ont des significations claires que vous pouvez exprimer à travers leurs noms. Des noms plus significatifs réduisent le nombre de bogues et rendent le code plus clair, deviennent une vraie différence avec un code plus grand / plus complexe. J'appellerais a au moins in_list et b slices , mais avec plus de contexte, cela pourrait être mieux.
Si vous ne souhaitez pas modifier votre liste d’entrée, vous pouvez utiliser un itérateur et le module itertools .
>>> from itertools import islice >>> a = [0, 1, 2, 3, 4, 5, 6, 7] >>> b = (3, 3, 2) >>> i = iter(a) >>> [list(islice(i, x)) for x in b] [[0, 1, 2], [3, 4, 5], [6, 7]]
Dans la première étape, vous créez un itérateur, qui commence au premier élément de a . Ensuite, vous itérez dans une compréhension de liste sur vos nombres dans b et à chaque étape, vous tirez en conséquence de nombreux éléments de l'itérateur et les stockez dans votre liste de résultats.
La syntaxe la plus "concise" serait:
ex_array = [0, 1, 2, 3, 4, 5, 6, 7] extuple = (3, 3, 2)
result = [ex_array[sum(extuple[:iii]):sum(extuple[:iii])+extuple[iii]] for iii in range(len(extuple))]
le résultat serait une liste des sous-listes attendues
vous pouvez utiliser la méthode de division de numpy
import numpy as np
a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
c = np.split(a, np.cumsum(b)[:-1])
for r in c:
print(r)
np.split (a, b) divise a par les indices de b le long d'un axe donné (0 par défaut). p >
Réutilisation de la fonction par paire de Comparer deux éléments adjacents dans la même liste , vous pouvez aussi:
from itertools import accumulate from more_itertools import pairwise a = [0, 1, 2, 3, 4, 5, 6, 7] b = (3, 3, 2) [a[slice(*s)] for s in pairwise(accumulate((0,)+b))]
Cela dit, la réponse np.split est probablement plus rapide (et plus facile à lire ).
C'est généralement un problème lorsque les affiches posent des questions sur un tableau, mais fournissent un exemple de liste. Ici, c'est simplement un ennui. Cela dit,
np.array_splitfonctionne un peu comme votre 2ème solution, en utilisant des tranches. Mais il attend un tuple cumulatif.@hpaulj Vous avez raison ... désolé pour ça.