Bonjour,
je cherche à faire un truc en apparence simple. J’ai une liste de fichiers (plusieurs milliers) qui portent un numéro de séquence.
Pour des raisons pratiques, je voudrais les regrouper dans des fichiers par paquet de 500. Je voudrais que le fichier résultant reprenne les numéros de séquence (borne inférieure et supérieure).
Ex:
comment vous y prendriez-vous (avec du code python) ?
fic1 fic2 fic3 = fic1-3
Merci
# 2/3 idées
Posté par T_T_T . Évalué à 3.
Je ne suis pas certain de comprendre tout le besoin, mais ton problème (et le label [NOOB INSIDE]) me fait te proposer
De lister les fichiers avec le module glob. Tu peux faire plus fin en combinant
os.listdir
et le module regexre
.Tu peux ordonner tes fichiers en précisant selon quelle clef tu souhaites classer (l'ordre alphabétique n'est pas nécessairement celui que tu souhaites).
Cette même fonction peut te permettre d'extraire l'information du ton nom de fichier pour le nom final du fichier concaténé.
Pour itérer 500 par 500, un truc vite fait donne
while lst:
head = lst[:500]
l = lst[500:]
print( head )
Une rapide recherche me donne aussi
[lst[i:i + 500] for i in range(0, len(lst), 500)]
Je te suggère de bien vérifier qu'il n'y a pas de trous dans la numérotation de tes fichiers, sinon tu vas t'arracher les cheveux dans quelques semaines!
[^] # Re: 2/3 idées
Posté par Xavier Maillard . Évalué à 1.
Tout d'abord, un grand merci pour ta réponse.
Je suis en train de chercher une solution moins « complexe ».
Je pars sur un dictionnaire listant les 2 bornes encadrant une année:
Sur la base de ça, j’ai un petit bout de code qui fait ce que je veux:byYear = {2012: [920,947],
2013: [948,999],
2014: [1000,1051],
2015: [1052,1103],
2016: [1104,1155],
2017: [1156,1203],
2018: [1204,1260],
2019: [1261,1312],
2020: [1313,1364],
2021: [1365,1378]}
Le soucis c’est que je ne veux pas maintenir ce dict dans mon code.with open('twic2012.pgn', 'w') as outfile:
for i in tqdm(range(920, 947)):
current_file = f"twic{i:03d}.pgn"
with open(current_file) as infile:
outfile.write(infile.read())
outfile.write("\n")
Pour la petite histoire le besoin est de me faciliter la vie pour télécharger les bases de The Week In Chess (https://theweekinchess.com/twic)
[^] # Re: 2/3 idées
Posté par T_T_T . Évalué à 3.
Peut-être pourrais-tu utiliser
filter
pour moins te prendre la tête avec les indices et les chiffres dans tous les sens (et les fichiers manquants)? Sur des quantités acceptables, ça devrait faire le taf.En code non testé écrit à la volée, ça donnerait
Mais je ne comprends pas trop comment tu ne veux pas maintenir ce
dict
dans ton fichier.Il me semble que c'est une info fondamentale, comment t'en sortir sans?
Tu peux séparer fonction et paramètres, mais je vois difficilement comment faire plus par rapport à ton besoin.
[^] # Re: 2/3 idées
Posté par Xavier Maillard . Évalué à 1.
Bonne idée.
En fait, mon petit programme devrait tenir un registre avec les infos suivantes:
- liste des fichiers téléchargés
- constitution d’une plus grande archive (quelles séquences dans quel fichier, etc.)
Je dois bien avouer que je réfléchis en avançant :)
Je compte bien faire une toute petite UI en tkinter pour permettre de faciliter 2 ou 3 choses
[^] # Re: 2/3 idées
Posté par Xavier Maillard . Évalué à 1.
[^] # Re: 2/3 idées
Posté par T_T_T . Évalué à 2.
Oui il faut que tu définisses ta liste de fichiers.
Comme je te le disais dans mon premier commentaire, quelque chose de ce genre devrait marcher pour avoir tous tes fichiers classés dans l'ordre.
[^] # Re: 2/3 idées
Posté par Xavier Maillard . Évalué à 1.
Super ton idée !
Ca me plait vraiment bien.
[^] # Re: 2/3 idées
Posté par _kaos_ . Évalué à 2. Dernière modification le 07 avril 2021 à 13:42.
Salut,
C'est pas super-complexifier la chose ?
Le dictionnaire peut être construit à la volée, sans nécessité de le maintenir "manuellement", dans une première passe qui "prépare" les listes de numéros dans l'ordre souhaité par année, puis une seconde boucle fait le boulot de concaténation. Pas besoin de
filter
;)Matricule 23415
[^] # Re: 2/3 idées
Posté par T_T_T . Évalué à 2. Dernière modification le 07 avril 2021 à 18:16.
Arf, c'est un éternel débat !
Si tu regardes bien la liste
byYear
, tu verras qu'on trouve tantôt 28 fichiers (cas particulier du début), tantôt 52, d'autres fois 57. Bref, on ne peut pas itérer de 52 en 52 par ex, principalement à cause du 57 de l'année 2018.Donc pourquoi? Peut-être y a-t-il des trous? Je ne sais pas.
Dans ces cas là, plutôt que me battre avec des
os.exists
et desif
de ci de là, j'aime bien lire ce qui est disponible et filtrer, généralement ça m'évite des noeuds au cerveau.Difficile à dire si c'est la bonne approche ici, je n'ai pas la vision sur tout le pb.
Et plus généralement, je trouve personnellement que faire plusieurs passes et être certain qu'on a la bonne correspondance est souvent plus difficile à faire marcher.
Quand je code, j'aime bien raisonner macro/fonctionnel (
filter
,map
,reduce
…), ensuite il ne "reste" qu'à mettre les bonnes implémentations aux bons endroits.Et puis ça a la mérite de présenter des pistes à un débutant python. ;)
[^] # Re: 2/3 idées
Posté par _kaos_ . Évalué à 3. Dernière modification le 08 avril 2021 à 06:25.
Salut,
Pas de problème avec un
os.listdir
, on ne liste que les fichiers présents, donc on peut construire le dictionnaire à la volée sansos.exists
ouif
, en n'imposant pas de contraintes de bornes inférieures/supérieures (dans la limite du raisonnable :p). Tout facile sans avoir recours à des méthodes avancées "compliquées".Et en ce qui concerne les débutants, j'éviterai justement de leur parler dès le début de notions avancées. Tu aurais aimé qu'on te parle de
lamdba
s dès ton premier cours d'informatique ? Mais ce n'est que mon avis. ;)PS : note qu'avec ton
glob
plus haut, tu fais exactement ça :pMatricule 23415
[^] # Re: 2/3 idées
Posté par T_T_T . Évalué à 1.
Ça se tient, ça se tient ;)
Je pense aussi que dans ce contexte, il n'était pas très clair d'où nous partions, quelles étaient les contraintes, et où nous voulions aller.
Donc différents niveaux de suppositions et propositions.
Enfin, gageons que nous avons aidé Xavier<, c'est le principal !
# Difficulté ?
Posté par _kaos_ . Évalué à 2.
Salut,
Je ne vois pas où tu bloque, même s'il y a des "trous" ou s'il fallait conserver un ordre.
Un début de code aiderait à mieux comprendre ce qui pose problème.
Que doit retourner :
fic1 fic3 fic4 fic5 fic7 fic9 fic10
?Plutôt :
fic1-10
fic1,3-5,7,9-10
fic1-1,3-5,7-7,9-10
Matricule 23415
[^] # Re: Difficulté ?
Posté par Xavier Maillard . Évalué à 1.
Salut,
dans l’exemple que tu donnes, ce serait plutôt fic1-10
[^] # Re: Difficulté ?
Posté par _kaos_ . Évalué à 3. Dernière modification le 07 avril 2021 à 07:44.
Salut,
C'est le cas le plus simple.
Vu le code proposé plus haut, le problème est (un peu) pris à l'envers si tu veux tout faire en une passe, car tu ne sauras jamais à l'avance la fin du nom de fichier, donc il faut passer par un fichier temporaire. Sinon, en deux passes sur les noms, ça se fait aussi, et vu la taille des données à stocker (une liste d'entiers), c'est kif-kif, et là, plus besoin du fichier temporaire.
Matricule 23415
[^] # Re: Difficulté ?
Posté par T_T_T . Évalué à 1.
S'il y a vraiment une difficulté pour trouver le nom final, il lest toujours possible, si la taille des donnés le permet de tout mettre dans un gros buffer temporaire à écrire sur disque à la fin.
Par exemple la classe
io.Stringio
.Mais une fois le "découpage" effectué, on accède facilement aux premier et dernier fichier et à leurs indices respectifs, donc j'avoue que je pense qu'il nous manque des petites briques pour bien tout comprendre.
# split
Posté par NeoX . Évalué à 3.
apparemment l'outil "split" en ligne de commande permet de découper le contenu d'un fichier en sous ensemble plus petit, par defaut en lot de 1000
donc si tu as ta liste de fichiers dans un seul fichier, et que tu veux en faire un liste par paquet de 500
split -n 500 fichier_complet masortie
te donnera masortie_01 masortie_02… avec 500 lignes de fichier_complet dedans
http://www.linuxfr-france.org.invalid/article/man-fr/man1/split-1.html
[^] # Re: split
Posté par Xavier Maillard . Évalué à 0.
Cette solution est inenvisageable car il s’agit de données structurées (PGN) sauf à parser le fichier mais ça sort du scope pour le moment.
[^] # Re: split
Posté par NeoX . Évalué à 3.
je suis parti de TA demande
je ne parles pas de couper les fichiers, mais bien de faire la liste des fichiers (dont tu disposes deja en fait) puis de prendre cette liste, de la couper en sous-liste de 500
ensuite ce que tu fais du contenu des fichiers à partir des sous-liste est un autre débat.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.