Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Mon code est lourd

15 réponses
Avatar
yves
Bonjour,

soit une séquence, un générateur (de tuples en l'occurrence)

('02', 'D', '27')
('02', 'L', '28')
('03', 'M', '01')
('03', 'M', '02')

Pour la petite histoire,
02 et 03 correspondent Í  Février et Mars
D 27; c'est dimanche 27, etc...


Je voudrais arriver Í  imprimer:
02
D 27
L 28
03
M 01
M 02

En repassant par un dictionnaire, j'ai ça:

#+begin_src python :results output :exports both

from pprint import pprint

def g():
yield('02', 'D', '27')
yield('02', 'L', '28')
yield('03', 'M', '01')
yield('03', 'M', '02')


dic = {}
l02,l03 = [],[]
for elt in g():
m , d, nd = elt
if m == "02":
l02.append((d,nd))
dic['02'] = l02
elif m == "03":
l03.append((d,nd))
dic['03'] = l03

pprint(dic)


#+end_src
#+RESULTS:
: {'02': [('D', '27'), ('L', '28')], '03': [('M', '01'), ('M', '02')]}

Et Í  partir du dictionnaire, l'impression finale est facile.

Mais cette méthode de conversion du générateur en dictionnaire me
paraͮt terriblement lourde, surtout qu'il y aura douze mois, c'est ͠
dire douze branchement if/elif

Vous auriez des suggestions d'écriture plus élégante ?


@+
--
Yves

10 réponses

1 2
Avatar
yves
Le Thu, 05 May 2022 19:40:34 +0000, yves a écrit:
Je voudrais arriver Í  imprimer:
02 D 27 L 28 03 M 01 M 02

Zut, la mise en page a sautée.
Je voudrais arriver Í  imprimer:
02
D 27
L 28
03
M 01
M 02
@+
--
Yves
Avatar
yves
Le Thu, 05 May 2022 19:42:13 +0000, yves a écrit:
Zut, la mise en page a sautée. Je voudrais arriver Í  imprimer:
02 D 27 L 28 03 M 01 M 02

Rezut.
02
D 27
L 28
03
M 01
M 02
@+
--
Yves
Avatar
yves
Le Thu, 05 May 2022 19:43:05 +0000, yves a écrit:
Zut, la mise en page a sautée. Je voudrais arriver Í  imprimer:
02 D 27 L 28 03 M 01 M 02

Rezut.

Bon, la mise en page est bonne dans Gnus, mais pas dans Pan 0.144
@+
--
Yves
Avatar
Benoit Izac
Bonjour,
Le 05/05/2022 Í  21:40, yves a écrit dans le message
<62742832$0$22051$ :
from pprint import pprint
def g():
yield('02', 'D', '27')
yield('02', 'L', '28')
yield('03', 'M', '01')
yield('03', 'M', '02')
dic = {}
l02,l03 = [],[]
for elt in g():
m , d, nd = elt
if m == "02":
l02.append((d,nd))
dic['02'] = l02
elif m == "03":
l03.append((d,nd))
dic['03'] = l03
pprint(dic)
[...]
Mais cette méthode de conversion du générateur en dictionnaire me
paraͮt terriblement lourde, surtout qu'il y aura douze mois, c'est ͠
dire douze branchement if/elif
Vous auriez des suggestions d'écriture plus élégante ?

dic = {}
for m, d, nd in g():
dic.setdefault(m, []).append((d, nd))
pprint(dic)
--
Benoit Izac
Avatar
Alain Ketterlin
yves writes:
('02', 'D', '27') ('02', 'L', '28') ('03', 'M', '01') ('03', 'M', '02')
Je voudrais arriver Í  imprimer:
02
D 27
L 28
03
M 01
M 02
def g():
yield('02', 'D', '27')
yield('02', 'L', '28')
yield('03', 'M', '01')
yield('03', 'M', '02')
dic = {}
l02,l03 = [],[]
for elt in g():
m , d, nd = elt
if m == "02":
l02.append((d,nd))
dic['02'] = l02
elif m == "03":
l03.append((d,nd))
dic['03'] = l03
pprint(dic)
Vous auriez des suggestions d'écriture plus élégante ?

Note qu'il est inutile de garder tes listes "en double", mais qu'il
faut alors tester leur présence dans le dictionnaire :
for elt in g():
m , d, nd = elt
if m not in dic:
dic[m] = []
dic[m].append ((d,nd))
C'est Í  peu près exactement ce que fait la méthode setdefault() de dict,
donc on peut raccourcir :
for m, d, nd in g():
dic.setdefault (m, []).append ((d,nd))
Note qu'on s'épargne aussi la variable "elt", puisqu'on peut
destructurer directement dans le "for".
Si ça ne te gène pas d'avoir des listes au lieu des paires, on peut
faire encore un peu plus court :
for m, *r in g():
dic.setdefault (m, []).append (r)
Cela dit, puisqu'il y a douze mois, et que j'imagine que tu auras des
dates dans chaque mois, autant créer d'emblée les listes vides, ce qui
épargne de répéter le test pour chaque date :
dic = { "{:02d}".format (i+1) : [] for i in range (12) }
for m,*r in g():
dic[m].append (r)
(Au passage : pourquoi utiliser des chaÍ®nes de caractères pour les mois ?
Un entier serait plus simple Í  manipuler.)
-- Alain.
Avatar
Dominique
Le 05/05/2022 Í  22:26, Alain Ketterlin a écrit :
dic = { "{:02d}".format (i+1) : [] for i in range (12) }

Je ne connaissais pas du tout cette méthode pour formater un
dictionnaire. C'est très intéressant, merci :-)
Je découvre l'utilisation du d après avoir, par hasard, testé x
(hexadécimal) puis, bien sÍ»r, o pour octal et b pour binaire.
Je comprends moins bien la sortie avec c et surtout au-delÍ  de 8 :
'0x08': [],
'0t': [],
'0n': [],
'0x0b': [],
'0x0c': []
Ce qu'il y a de bien avec Python, c'est que je n'en verrai jamais le
bout :-)
Dominique
Avatar
Alain Ketterlin
Dominique writes:
Le 05/05/2022 Í  22:26, Alain Ketterlin a écrit :
dic = { "{:02d}".format (i+1) : [] for i in range (12) }

Je ne connaissais pas du tout cette méthode pour formater un
dictionnaire. C'est très intéressant, merci :-)

Pour être précis : il ne s'agit pas de formater un dictionnaire, mais de
formater des nombres qui servent de clés dans le dictionnaire.
En fait, je préfère « "%02d" % (i+1) » mais c'est parce que j'ai plus
l'habitude de printf en C.
Je découvre l'utilisation du d après avoir, par hasard, testé x
(hexadécimal) puis, bien sÍ»r, o pour octal et b pour binaire.

Oui, ce sont toutes les façons de formater un nombre entier. "02d"
signifie "écriture décimale" (d) sur 2 caractères au moins, en
remplissant Í  gauche avec des "0" si nécessaire.
Je comprends moins bien la sortie avec c et surtout au-delÍ  de 8 :

"c" signifie caractère, le préfixe "0" est pris comme caractère de
remplissage, et le "2" signifie toujours la largeur minimale du
résultat.
'0x08': [],
'0t': [],
'0n': [],
'0x0b': [],
'0x0c': []

Cela revient Í  demander de formater des caractères de codes 8, 9, etc.
sur 2 caractères. Toutes les chaÍ®nes ci-dessus ont bien une longueur 2,
mais il faut utiliser des notations pour représenter ceux qui n'ont pas
de glyphe particulier (tous ici). Avec "{:02c}".format(97), on obtient
'0a' ('a' est le caractère de code 97). Le cas de 9 et 10 est spécial
parce qu'il existe une notation, mais 't' par exemple a exactement le
même sens que 'x09' (et 'n' que ' x0a').
-- Alain.
Avatar
yves
Le Thu, 05 May 2022 22:12:08 +0200, Benoit Izac a écrit:
Vous auriez des suggestions d'écriture plus élégante ?

dic = {}
for m, d, nd in g():
dic.setdefault(m, []).append((d, nd))
pprint(dic)

Merci, c'est en plein dans le mille.
@+
--
Yves
Avatar
yves
Le Thu, 05 May 2022 22:26:20 +0200, Alain Ketterlin a écrit:
(Au passage : pourquoi utiliser des chaÍ®nes de caractères pour les mois
?
Un entier serait plus simple Í  manipuler.)

Merci pour toute cette matière Í  réflexion.
Pour ce qui est des chaÍ®nes de caractères, c'est surtout que j'ai épuré
au maximum mon exposé du problème.
En réalité, ma source de donnée actuelle c'est plutÍ´t ce code lÍ :
***
#+begin_src python :results output :exports both
from datetime import datetime, timedelta, date
def genereXdates2():
dateDepart = "26012022"
dateFin = "07052022"
depart = datetime.strptime(dateDepart, '%d%m%Y')
fin = datetime.strptime(dateFin, '%d%m%Y')
date = depart
dict_transcodage = {"6": "S", "0": "D", "1":"L", "2":"M", "3":"M",
"4":"J", "5":"V"}
while date != fin:
yield(date.strftime("%m"),dict_transcodage[date.strftime('%w')],date.strftime('%d'))
date = date + timedelta(1)
for elt in genereXdates2():
print(elt)
#+end_src
****
@+
--
Yves
Avatar
Dominique
Le 06/05/2022 Í  11:30, Alain Ketterlin a écrit :
"c" signifie caractère, le préfixe "0" est pris comme caractère de
remplissage, et le "2" signifie toujours la largeur minimale du
résultat.
'0x08': [],
'0t': [],
'0n': [],
'0x0b': [],
'0x0c': []


Merci Alain. Je vais regarder ça de plus près, quand j'aurai le temps, Í 
la retraite... dans un mois :-)
1 2