Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Alain BARTHE
Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
Tu peux essayer :
for e in filter (<fonction>, list1): <instruction>
Avec <fonction> qui peut être une fonction booléenne qui fasse ton filtrage (si cette fonction existe déjà) ou une lambda expression si tu ne veux pas surcharger ton espace de noms.
Ex:
for e in filter (lambda x: x not in list2, list1): <instruction>
Le gain n'est quand même pas énorme par rapport à la syntaxe initiale.
Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste
privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci :
>for e in list1 :
> if not e in list2 :
> <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur
deux instructions, et d'approfondir inutilement l'indentation.
J'avais envisagé les listes en intention, ce qui me donnait ceci :
>for e in [e for e in list1 if e not in list2]:
> <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas :
>for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
Tu peux essayer :
for e in filter (<fonction>, list1):
<instruction>
Avec <fonction> qui peut être une fonction booléenne qui fasse ton
filtrage (si cette fonction existe déjà) ou une lambda expression si tu
ne veux pas surcharger ton espace de noms.
Ex:
for e in filter (lambda x: x not in list2, list1):
<instruction>
Le gain n'est quand même pas énorme par rapport à la syntaxe initiale.
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
Tu peux essayer :
for e in filter (<fonction>, list1): <instruction>
Avec <fonction> qui peut être une fonction booléenne qui fasse ton filtrage (si cette fonction existe déjà) ou une lambda expression si tu ne veux pas surcharger ton espace de noms.
Ex:
for e in filter (lambda x: x not in list2, list1): <instruction>
Le gain n'est quand même pas énorme par rapport à la syntaxe initiale.
Alain BARTHE
Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste
privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci :
>for e in list1 :
> if not e in list2 :
> <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur
deux instructions, et d'approfondir inutilement l'indentation.
Ca va surement en faire hurler plus d'un mais j'aime bien
(et puis c'est vendredi) :
for e in list1:
if e in list2: continue
<instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles :
on peut mettre plein de tests en début de boucle, pour ignorer toute une
série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles"
perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas
forcément plus lisible que quelques instructions continue bien
identifiées en début de boucle.
J'avais envisagé les listes en intention, ce qui me donnait ceci :
>for e in [e for e in list1 if e not in list2]:
> <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas :
>for e in list1 if e not in list2 :
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
Pierre Maurette
Kaoron, le 06/11/2009 a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
Mais elle a l'avantage d'être maintenable sans risque de casser vicieusement un truc qui marche. Je suis revenu de mon époque "tout doiot tenir sur une seule ligne" qui me générait des trucs qui me prenaient dix minutes à détricoter pour modifier par exemple un test. Les deux trucs proposés par Alain BARTHE sont parfaits sur le plan de la maintenabilité.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
Si vous trouvez ça illisible, le problème est peut-être chez vous ;-) Vous pouvez compacter, et pour moi ça reste très lisible:
[instructions(_) for _ in list1 if _ not in list2] ou [instructions(_) for _ in filter(<fonction>, list1)]
Selon ce que fait <instructions> vous codez une fonction ou utilisez un lambda. Vous pouvez aussi regarder du coté de map et reduce.
Je me répète, j'ai perdu pas mal de temps à chercher à coder élégant. Résultat, je perdais du temps, ce n'était *pas* élégant parce qu'illisible, bref, j'ai changé mon fusil d'épaule et je vais au plus rapide et naturel. A vous de voir...
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
-- Pierre Maurette
Kaoron, le 06/11/2009 a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste
privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci :
>for e in list1 :
> if not e in list2 :
> <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux
instructions, et d'approfondir inutilement l'indentation.
Mais elle a l'avantage d'être maintenable sans risque de casser
vicieusement un truc qui marche. Je suis revenu de mon époque "tout
doiot tenir sur une seule ligne" qui me générait des trucs qui me
prenaient dix minutes à détricoter pour modifier par exemple un test.
Les deux trucs proposés par Alain BARTHE sont parfaits sur le plan de
la maintenabilité.
J'avais envisagé les listes en intention, ce qui me donnait ceci :
>for e in [e for e in list1 if e not in list2]:
> <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
Si vous trouvez ça illisible, le problème est peut-être chez vous ;-)
Vous pouvez compacter, et pour moi ça reste très lisible:
[instructions(_) for _ in list1 if _ not in list2]
ou
[instructions(_) for _ in filter(<fonction>, list1)]
Selon ce que fait <instructions> vous codez une fonction ou utilisez un
lambda. Vous pouvez aussi regarder du coté de map et reduce.
Je me répète, j'ai perdu pas mal de temps à chercher à coder élégant.
Résultat, je perdais du temps, ce n'était *pas* élégant parce
qu'illisible, bref, j'ai changé mon fusil d'épaule et je vais au plus
rapide et naturel. A vous de voir...
La syntaxe suivante dérivée des listes en intention ne fonctionne pas :
>for e in list1 if e not in list2 :
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Elle a le désavantage de diviser la définition de mon ensemble itéré sur deux instructions, et d'approfondir inutilement l'indentation.
Mais elle a l'avantage d'être maintenable sans risque de casser vicieusement un truc qui marche. Je suis revenu de mon époque "tout doiot tenir sur une seule ligne" qui me générait des trucs qui me prenaient dix minutes à détricoter pour modifier par exemple un test. Les deux trucs proposés par Alain BARTHE sont parfaits sur le plan de la maintenabilité.
J'avais envisagé les listes en intention, ce qui me donnait ceci : >for e in [e for e in list1 if e not in list2]: > <instructions>
Mais comme vous pouvez l'apprécier, ça n'a plus grand chose de lisible.
Si vous trouvez ça illisible, le problème est peut-être chez vous ;-) Vous pouvez compacter, et pour moi ça reste très lisible:
[instructions(_) for _ in list1 if _ not in list2] ou [instructions(_) for _ in filter(<fonction>, list1)]
Selon ce que fait <instructions> vous codez une fonction ou utilisez un lambda. Vous pouvez aussi regarder du coté de map et reduce.
Je me répète, j'ai perdu pas mal de temps à chercher à coder élégant. Résultat, je perdais du temps, ce n'était *pas* élégant parce qu'illisible, bref, j'ai changé mon fusil d'épaule et je vais au plus rapide et naturel. A vous de voir...
La syntaxe suivante dérivée des listes en intention ne fonctionne pas : >for e in list1 if e not in list2 :
Avez-vous une meilleure solution à me proposer ?
-- Pierre Maurette
PIGUET Bruno
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?
Dans un cas simple, j'ai remplacé : l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = l3 for i in l5: if not i in l3: l.append(i)
par : s5 = set(range(5, 1000, 5)) s3 = set(range(3, 1000, 3)) s = s3 | s5
avec un bon gain d'efficacité.
Bruno.
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste
privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci :
>for e in list1 :
> if not e in list2 :
> <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles
("sets") ?
Dans un cas simple, j'ai remplacé :
l5 = range(5, 1000, 5)
l3 = range(3, 1000, 3)
l = l3
for i in l5:
if not i in l3:
l.append(i)
par :
s5 = set(range(5, 1000, 5))
s3 = set(range(3, 1000, 3))
s = s3 | s5
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?
Dans un cas simple, j'ai remplacé : l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = l3 for i in l5: if not i in l3: l.append(i)
par : s5 = set(range(5, 1000, 5)) s3 = set(range(3, 1000, 3)) s = s3 | s5
avec un bon gain d'efficacité.
Bruno.
Pierre Maurette
PIGUET Bruno, le 06/11/2009 a écrit :
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?
Dans un cas simple, j'ai remplacé : l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = l3 for i in l5: if not i in l3: l.append(i)
par : s5 = set(range(5, 1000, 5)) s3 = set(range(3, 1000, 3)) s = s3 | s5
Je pense que l'opérateur, c'est - et non | (union).
on peut penser à
for e in set(list1) - set(list2): etc.
Mais avec les set on change d'algo. Même sans parler de l'ordre. Dans la question on éliminait toutes les occurences d'un élément s'il était présent dans list2, mais on traitait autant de fois les autres qu'ils étaient dans list1. Avec les set, on élimine les doublons (et plus).
> avec un bon gain d'efficacité.
Sûr ?
-- Pierre Maurette
PIGUET Bruno, le 06/11/2009 a écrit :
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste
privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci :
>for e in list1 :
> if not e in list2 :
> <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles
("sets") ?
Dans un cas simple, j'ai remplacé :
l5 = range(5, 1000, 5)
l3 = range(3, 1000, 3)
l = l3
for i in l5:
if not i in l3:
l.append(i)
par :
s5 = set(range(5, 1000, 5))
s3 = set(range(3, 1000, 3))
s = s3 | s5
Je pense que l'opérateur, c'est - et non | (union).
on peut penser à
for e in set(list1) - set(list2):
etc.
Mais avec les set on change d'algo. Même sans parler de l'ordre. Dans
la question on éliminait toutes les occurences d'un élément s'il était
présent dans list2, mais on traitait autant de fois les autres qu'ils
étaient dans list1. Avec les set, on élimine les doublons (et plus).
Le Fri, 06 Nov 2009 10:55:38 +0100, Kaoron a écrit :
Bonjour,
Pouvez-vous m'enrichir d'une méthode élégante pour itérer sur une liste privée de certains de ses éléments ?
La solution que j'emploie actuellement est celle-ci : >for e in list1 : > if not e in list2 : > <instructions>
Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?
Dans un cas simple, j'ai remplacé : l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = l3 for i in l5: if not i in l3: l.append(i)
par : s5 = set(range(5, 1000, 5)) s3 = set(range(3, 1000, 3)) s = s3 | s5
Je pense que l'opérateur, c'est - et non | (union).
on peut penser à
for e in set(list1) - set(list2): etc.
Mais avec les set on change d'algo. Même sans parler de l'ordre. Dans la question on éliminait toutes les occurences d'un élément s'il était présent dans list2, mais on traitait autant de fois les autres qu'ils étaient dans list1. Avec les set, on élimine les doublons (et plus).
Sûr. Au moins un facteur N/log(N) probablement, où N est la taill e du deuxième ensemble. Sauf cas très particulier.
-- Alain.
PIGUET Bruno
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par : "Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une liste unique en disant "si un nouvel élément n'est pas (déjà) dans la liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était bien "|". Mais cette transformation d'exclusion en union n'est pas forcément celui que souhaitais l'OP. D'où mon introduction prudente.
> avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu en mesurer, oui.
Bruno.
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par :
"Est-ce une situation où il est possible d'utiliser les ensembles
("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une
liste unique en disant "si un nouvel élément n'est pas (déjà) dans la
liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était
bien "|".
Mais cette transformation d'exclusion en union n'est pas forcément
celui que souhaitais l'OP. D'où mon introduction prudente.
> avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu
en mesurer, oui.
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par : "Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une liste unique en disant "si un nouvel élément n'est pas (déjà) dans la liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était bien "|". Mais cette transformation d'exclusion en union n'est pas forcément celui que souhaitais l'OP. D'où mon introduction prudente.
> avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu en mesurer, oui.
Bruno.
Pierre Maurette
PIGUET Bruno, le 06/11/2009 a écrit :
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par : "Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une liste unique en disant "si un nouvel élément n'est pas (déjà) dans la liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était bien "|". Mais cette transformation d'exclusion en union n'est pas forcément celui que souhaitais l'OP. D'où mon introduction prudente.
Désolé. Je ne pensais pas que vous êtiez aussi éloigné que ça du problème de l'OP, et comme souvent j'ai lu en diagonale et ce que je *voulais* lire, à savoir:
l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = [] #et non l = l3 !!! for i in l5: if not i in l3: l.append(i)
ce qui fait ce que veut l'OP, aux doublons près bien entendu.
Ce que vous faisiez, c'est la liste des multiples - non nuls - de 3 et de 5, en faisant attention à ne pas inclure deux fois les multiples communs, donc les multiples de 15. C'est effectivement complètement un problème d'ensemble. Le gain de performance reste énorme même en faisant s = sorted(list(s3 | s5))
Remarque: par rapport à la solution bourrin, on est - dans certaines conditions de test - ~10 fois plus rapide en faisant:
l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l15 = range(15, 1000, 15) l = l3 for i in l5: if not i in l15: l.append(i)
mais ça reste au moins 5 fois plus lent qu'avec les ensembles, même en convertissant le résultat en liste triée.
avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu en mesurer, oui.
J'ai mesuré également, quand le problème est adapté aux ensembles, la différence est monstrueuse, effectivement. Il est d'ailleurs clair que set(range()) est traité spécifiquement, et non pas comme set(listequelconque()).
-- Pierre Maurette
PIGUET Bruno, le 06/11/2009 a écrit :
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par :
"Est-ce une situation où il est possible d'utiliser les ensembles
("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une
liste unique en disant "si un nouvel élément n'est pas (déjà) dans la
liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était
bien "|".
Mais cette transformation d'exclusion en union n'est pas forcément
celui que souhaitais l'OP. D'où mon introduction prudente.
Désolé. Je ne pensais pas que vous êtiez aussi éloigné que ça du
problème de l'OP, et comme souvent j'ai lu en diagonale et ce que je
*voulais* lire, à savoir:
l5 = range(5, 1000, 5)
l3 = range(3, 1000, 3)
l = [] #et non l = l3 !!!
for i in l5:
if not i in l3:
l.append(i)
ce qui fait ce que veut l'OP, aux doublons près bien entendu.
Ce que vous faisiez, c'est la liste des multiples - non nuls - de 3 et
de 5, en faisant attention à ne pas inclure deux fois les multiples
communs, donc les multiples de 15.
C'est effectivement complètement un problème d'ensemble. Le gain de
performance reste énorme même en faisant
s = sorted(list(s3 | s5))
Remarque: par rapport à la solution bourrin, on est - dans certaines
conditions de test - ~10 fois plus rapide en faisant:
l5 = range(5, 1000, 5)
l3 = range(3, 1000, 3)
l15 = range(15, 1000, 15)
l = l3
for i in l5:
if not i in l15:
l.append(i)
mais ça reste au moins 5 fois plus lent qu'avec les ensembles, même en
convertissant le résultat en liste triée.
avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu
en mesurer, oui.
J'ai mesuré également, quand le problème est adapté aux ensembles, la
différence est monstrueuse, effectivement. Il est d'ailleurs clair que
set(range()) est traité spécifiquement, et non pas comme
set(listequelconque()).
Le Fri, 06 Nov 2009 14:54:50 +0100, Pierre Maurette a écrit :
Mais avec les set on change d'algo.
C'est pour ça que j'ai commencé mon message par : "Est-ce une situation où il est possible d'utiliser les ensembles ("sets") ?"
Le premier bout de code que j'ai recopié était une façon de faire une liste unique en disant "si un nouvel élément n'est pas (déjà) dans la liste, je l'ajoute (append)". Donc l'opérateur de set correspondant était bien "|". Mais cette transformation d'exclusion en union n'est pas forcément celui que souhaitais l'OP. D'où mon introduction prudente.
Désolé. Je ne pensais pas que vous êtiez aussi éloigné que ça du problème de l'OP, et comme souvent j'ai lu en diagonale et ce que je *voulais* lire, à savoir:
l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l = [] #et non l = l3 !!! for i in l5: if not i in l3: l.append(i)
ce qui fait ce que veut l'OP, aux doublons près bien entendu.
Ce que vous faisiez, c'est la liste des multiples - non nuls - de 3 et de 5, en faisant attention à ne pas inclure deux fois les multiples communs, donc les multiples de 15. C'est effectivement complètement un problème d'ensemble. Le gain de performance reste énorme même en faisant s = sorted(list(s3 | s5))
Remarque: par rapport à la solution bourrin, on est - dans certaines conditions de test - ~10 fois plus rapide en faisant:
l5 = range(5, 1000, 5) l3 = range(3, 1000, 3) l15 = range(15, 1000, 15) l = l3 for i in l5: if not i in l15: l.append(i)
mais ça reste au moins 5 fois plus lent qu'avec les ensembles, même en convertissant le résultat en liste triée.
avec un bon gain d'efficacité.
Sûr ?
Le bon benchmarking est un art difficile. Sur mon cas, et ce que j'ai pu en mesurer, oui.
J'ai mesuré également, quand le problème est adapté aux ensembles, la différence est monstrueuse, effectivement. Il est d'ailleurs clair que set(range()) est traité spécifiquement, et non pas comme set(listequelconque()).
-- Pierre Maurette
Kaoron
Alain BARTHE wrote:
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une proposition de changement de la syntaxe de for sur la ML python-dev :
C'est le genre d'enrichissement que j'étais venu chercher, merci beaucoup :)
Alain BARTHE wrote:
Ca va surement en faire hurler plus d'un mais j'aime bien
(et puis c'est vendredi) :
for e in list1:
if e in list2: continue
<instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles :
on peut mettre plein de tests en début de boucle, pour ignorer toute une
série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles"
perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas
forcément plus lisible que quelques instructions continue bien
identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et
explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une
proposition de changement de la syntaxe de for sur la ML python-dev :
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une proposition de changement de la syntaxe de for sur la ML python-dev :
C'est le genre d'enrichissement que j'étais venu chercher, merci beaucoup :)
Alain BARTHE
Kaoron a écrit :
Alain BARTHE wrote:
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une proposition de changement de la syntaxe de for sur la ML python-dev :
C'est le genre d'enrichissement que j'étais venu chercher, merci beaucoup :)
De rien :)
Kaoron a écrit :
Alain BARTHE wrote:
Ca va surement en faire hurler plus d'un mais j'aime bien
(et puis c'est vendredi) :
for e in list1:
if e in list2: continue
<instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles :
on peut mettre plein de tests en début de boucle, pour ignorer toute une
série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles"
perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas
forcément plus lisible que quelques instructions continue bien
identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et
explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une
proposition de changement de la syntaxe de for sur la ML python-dev :
Ca va surement en faire hurler plus d'un mais j'aime bien (et puis c'est vendredi) :
for e in list1: if e in list2: continue <instructions-sans-approfondir-inutilement-l-indentation>
J'adore faire des trucs comme ça dans les boucles : on peut mettre plein de tests en début de boucle, pour ignorer toute une série de cas, sans approfondir inutilement...
Ca évite parfois de se retrouver avec le bloc d'instructions "utiles" perdu dans une 3eme, 4eme niveau d'indentation, ce qui n'est pas forcément plus lisible que quelques instructions continue bien identifiées en début de boucle.
Les deux solutions que vous proposez me paraissent très lisibles et explicites, ce qui est en quelque sorte mon critère suprême d'élégance.
Je vois par ailleurs que les deux ont été proposées en réponse à une proposition de changement de la syntaxe de for sur la ML python-dev :