Je cherche a créer un générateur qui découpe une string une fois en un morceau de 8 caractères et ensuite en morceaux de 16 jusqu'à la fin de la ligne.
J'ai ça, mais le problème c'est qu'il faudrait que je change l'argument du pas de range après la première itération du générateur. Je maitrise pas trop les générateurs du coup je bug un peu sur comment régler mon soucis.
def chunk_long(line):
"""Générateur qui split une line tout les 16 caractères après avoir splitté une fois après 8 char """
for start in range(0, len(line), 8): # après la première itération j'aimerai que l'argument 8 de range devienne 16
if start == 0:
yield line[start:start+8]
else:
yield line[start:start+16]
J'imagine que je pourrais régler mon soucis en créant un générateur perso pour remplacer range() mais il y a peut être une solution plus simple que je ne vois pas.
Par exemple: s="012345670123456789abcdef0123456789abcdefghj" a, b = s[:8], s[8:] L=[a]+[b[i:i+16] for i in range(0, len(b), 16)] print(L) Ce qui donne: ['01234567', '0123456789abcdef', '0123456789abcdef', 'ghj']
Le Tout est souvent plus grand que la somme de ses parties.
Je ne sais pas si Jojuss veut absolument un générateur ou simplement découper sa ligne. Ça se fait facilement avec une compréhension, dans le même style que le code de josmiley: s="012345670123456789abcdef0123456789abcdefghj" L=[s[i:i+16] or s[:8] for i in range(-8, len(s), 16)] print(L)
Le Tout est souvent plus grand que la somme de ses parties.
from textwrap import wrap
s = "012345670123456789abcdef0123456789abcdefghj"
res = [s[:8]] + wrap(s[8:], 16)
print('\n'.join(res))
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
en partant de ton code et faisant une autre boucle for + yield dans le else (j'ai laissé les print de debug):
def chunk_long(line):
"""Générateur qui split une line tout les 16 caractères après avoir splitté une fois après 8 char """
pas=8
for start in range(0, len(line), pas): # après la première itération j'aimerai que l'argument 8 de range devienne 16
print("start:",start)
if start == 0:
print("pas:",pas)
yield line[start:start+pas]
else:
pas=16
for start in range(start,len(line),pas):
print("start:",start)
yield line[start:start+pas]
break
s = 'azertyuiopqsdfghjklmwxcvbn012345679AZERRTYUIOP'
for i in chunk_long(s):
print(i)
La raison pour laquelle josmiley met "or s[:8]" est que si le premier indice est négatif, s[-8: 8] donne une chaîne vide On part de la fin - 8, donc 16-8 jusqu'à +8, ce qui donne bien une chaîne vide. @umfred: As-tu besoin de tester si start vaut 0 et mettre pas à 16 si c'est le cas? Puisque le pas sera de 16 pour toujours après la première passe, mets le d'office à 16, sans test. En fait, c'est le for qui bloque avec son range. Avec un while, ça marcherait. Et tu n'aurais pas besoin de 2 boucles.
Le Tout est souvent plus grand que la somme de ses parties.
La raison pour laquelle josmiley met "or s[:8]" est que si le premier indice est négatif, s[-8: 8] donne une chaîne vide On part de la fin - 8, donc 16-8 jusqu'à +8, ce qui donne bien une chaîne vide.
ça dépend de la taille de la chaine.
après correction:
def chunk_long(s):
i = 0
for j in range(8, len(s)+16, 16):
yield s[i:j]
i = j
@josmiley: Je pense que c'est le plus court qu'on peut faire avec un générateur. Je l'ai testé avec toutes sortes de longueurs: 0, 4, 8, 9, 24, etc. La solution de fred1599 est très bien mais, comme la mienne, ne comporte pas de générateur codé par l'utilisateur.
Le Tout est souvent plus grand que la somme de ses parties.
J'ai au final opté pour la solution de LoupSolitaire, c'est pas beaucoup plus long et plus compréhensible que d'essayer de tout caler d'un coup. Ceci dit toutes les solutions proposées sont intéressantes, toujours sympa de voir comment chacun trouve une solution différente à un problème commun.
J'ai au final opté pour la solution de LoupSolitaire, c'est pas beaucoup plus long et plus compréhensible que d'essayer de tout caler d'un coup. Ceci dit toutes les solutions proposées sont intéressantes, toujours sympa de voir comment chacun trouve une solution différente à un problème commun.
si t'es pas à l'aise avec les lambda, en version classique ça donne ça:
def chunk_long(s):
for j in range(-8, len(s), 16):
yield s[j-len(s):j+16]
Python c'est bon, mangez-en.
modifier le comportement de range()
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Blond, bouclé, toujours le sourire aux lèvres...
Le Tout est souvent plus grand que la somme de ses parties.
Python c'est bon, mangez-en.
Le Tout est souvent plus grand que la somme de ses parties.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
Python c'est bon, mangez-en.
Le Tout est souvent plus grand que la somme de ses parties.
Python c'est bon, mangez-en.
Le Tout est souvent plus grand que la somme de ses parties.
Python c'est bon, mangez-en.
Le Tout est souvent plus grand que la somme de ses parties.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.