Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
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
NicolasP
Le 22/10/2010 14:46, NicolasP a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ....
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Nicolas
Rectification : La partie alphabétique est soit présente soit absente dans les deux éléments à comparer Donc "1" < "A1" n'a pas de sens.
Le 22/10/2010 14:46, NicolasP a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
....
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Nicolas
Rectification :
La partie alphabétique est soit présente soit absente dans les deux éléments à comparer
Donc "1" < "A1" n'a pas de sens.
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ....
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Nicolas
Rectification : La partie alphabétique est soit présente soit absente dans les deux éléments à comparer Donc "1" < "A1" n'a pas de sens.
def couple(s): t = s.rstrip("0123456789") n = s[len(t):] return (t,int(n))
ensuite tu peux faire couple(s1) < couple(s2)
-- Alain.
Pierre Maurette
NicolasP, le 10/22/2010 a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être: re.match('(D*)(.*)', chaine).groups()
ou plutôt: pat = re.compile('(D*)(.*)') #... pat.match(chaine).groups()
un test: for item in ('PIERRE', '128', 'PIERRE128', ''): print pat.match(item).groups()
-- Pierre Maurette
NicolasP, le 10/22/2010 a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour
un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une
partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie numérique et
traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être:
re.match('(D*)(.*)', chaine).groups()
ou plutôt:
pat = re.compile('(D*)(.*)')
#...
pat.match(chaine).groups()
un test:
for item in ('PIERRE', '128', 'PIERRE128', ''):
print pat.match(item).groups()
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être: re.match('(D*)(.*)', chaine).groups()
ou plutôt: pat = re.compile('(D*)(.*)') #... pat.match(chaine).groups()
un test: for item in ('PIERRE', '128', 'PIERRE128', ''): print pat.match(item).groups()
-- Pierre Maurette
Pierre Quentel
On 22 oct, 14:46, NicolasP wrote:
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractère s pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie num érique et traiter la partie numérique comme un nombre et non pas comme une chaine.
mais le dernier test échoue : pouquoi B1 serait-il inférieur à AA1 ? dans l'ordre alphabétique normal, B est après AA
A+ Pierre
On 22 oct, 14:46, NicolasP <nicol...@aaton.com> wrote:
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractère s pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie num érique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Je cherche à faire une fonction de comparaison de chaine de caractère s pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie num érique et traiter la partie numérique comme un nombre et non pas comme une chaine.
mais le dernier test échoue : pouquoi B1 serait-il inférieur à AA1 ? dans l'ordre alphabétique normal, B est après AA
A+ Pierre
Daniel Gallavardin
Le 22/10/2010 14:46, NicolasP a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Nicolas
Bonjour, C'est généralisable assez facilement en décomposant la chaine en tronçons numériques ou non, puis en convertissant les tronçons de chiffres en nombre entiers:
def order(data, rc=re.compile('[0-9]+|[^0-9]+')): '''Critere de tri''' tmp = [] for item in rc.findall(data): try: item = int(item) except ValueError: pass tmp.append(item) return tuple(tmp)
order('A10') # Cas simple
('A', 10)
order('Page15_ligne234_caractere82+$~33d2!!!') # ou complexe
Ce critère de tri est d'usage assez général, mais il est possible d'en fabiquer sur mesure pour tous les cas tordus.
Daniel
Le 22/10/2010 14:46, NicolasP a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères
pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et
d'une partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie
numérique et traiter la partie numérique comme un nombre et non pas
comme une chaine.
Comment faire cela simplement ?
Nicolas
Bonjour,
C'est généralisable assez facilement en décomposant la chaine en
tronçons numériques ou non, puis en convertissant les tronçons de
chiffres en nombre entiers:
def order(data, rc=re.compile('[0-9]+|[^0-9]+')):
'''Critere de tri'''
tmp = []
for item in rc.findall(data):
try:
item = int(item)
except ValueError:
pass
tmp.append(item)
return tuple(tmp)
order('A10') # Cas simple
('A', 10)
order('Page15_ligne234_caractere82+$~33d2!!!') # ou complexe
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Nicolas
Bonjour, C'est généralisable assez facilement en décomposant la chaine en tronçons numériques ou non, puis en convertissant les tronçons de chiffres en nombre entiers:
def order(data, rc=re.compile('[0-9]+|[^0-9]+')): '''Critere de tri''' tmp = [] for item in rc.findall(data): try: item = int(item) except ValueError: pass tmp.append(item) return tuple(tmp)
order('A10') # Cas simple
('A', 10)
order('Page15_ligne234_caractere82+$~33d2!!!') # ou complexe
Ce critère de tri est d'usage assez général, mais il est possible d'en fabiquer sur mesure pour tous les cas tordus.
Daniel
NicolasP
Le 22/10/2010 15:25, Alain Ketterlin a écrit :
NicolasP writes:
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
def couple(s): t = s.rstrip("0123456789") n = s[len(t):] return (t,int(n))
ensuite tu peux faire couple(s1)< couple(s2)
-- Alain.
J'utilise ça (merci google) : e1 = re.findall(r'(d+|D+)', pin_name)
Pour moi la fonction couple est plus claire.
Merci
Nicolas
Le 22/10/2010 15:25, Alain Ketterlin a écrit :
NicolasP<nicolasp@aaton.com> writes:
Je cherche à faire une fonction de comparaison de chaine de caractères
pour un tri "alpha-numérique". Les chaines sont composées d'une partie
alphabétique(facultative) et d'une partie numérique.
def couple(s):
t = s.rstrip("0123456789")
n = s[len(t):]
return (t,int(n))
ensuite tu peux faire couple(s1)< couple(s2)
-- Alain.
J'utilise ça (merci google) :
e1 = re.findall(r'(d+|D+)', pin_name)
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
def couple(s): t = s.rstrip("0123456789") n = s[len(t):] return (t,int(n))
ensuite tu peux faire couple(s1)< couple(s2)
-- Alain.
J'utilise ça (merci google) : e1 = re.findall(r'(d+|D+)', pin_name)
Pour moi la fonction couple est plus claire.
Merci
Nicolas
NicolasP
Le 22/10/2010 16:46, Pierre Maurette a écrit :
NicolasP, le 10/22/2010 a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être: re.match('(D*)(.*)', chaine).groups()
ou plutôt: pat = re.compile('(D*)(.*)') #... pat.match(chaine).groups()
un test: for item in ('PIERRE', '128', 'PIERRE128', ''): print pat.match(item).groups()
Une expression régulière marche bien mais je trouve la solution d'Alain Ketterlin plus lisible.
Nicolas
Le 22/10/2010 16:46, Pierre Maurette a écrit :
NicolasP, le 10/22/2010 a écrit :
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
Soit :
"1" < "10"
"9" < "10"
"A1" < "A10"
"A9" < "A10"
"AA1" < "AA10"
"AA9" < "AA10"
"1" < "A1"
"A1" < "AA1"
"B1" < "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être:
re.match('(D*)(.*)', chaine).groups()
ou plutôt:
pat = re.compile('(D*)(.*)')
#...
pat.match(chaine).groups()
un test:
for item in ('PIERRE', '128', 'PIERRE128', ''):
print pat.match(item).groups()
Une expression régulière marche bien mais je trouve la solution d'Alain Ketterlin plus lisible.
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1" < "10" "9" < "10" "A1" < "A10" "A9" < "A10" "AA1" < "AA10" "AA9" < "AA10"
"1" < "A1" "A1" < "AA1" "B1" < "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
Comment faire cela simplement ?
Peut-être: re.match('(D*)(.*)', chaine).groups()
ou plutôt: pat = re.compile('(D*)(.*)') #... pat.match(chaine).groups()
un test: for item in ('PIERRE', '128', 'PIERRE128', ''): print pat.match(item).groups()
Une expression régulière marche bien mais je trouve la solution d'Alain Ketterlin plus lisible.
Nicolas
NicolasP
On 22 oct, 14:46, NicolasP wrote:
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1"< "10" "9"< "10" "A1"< "A10" "A9"< "A10" "AA1"< "AA10" "AA9"< "AA10"
"1"< "A1" "A1"< "AA1" "B1"< "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
assert alphanum("1")<alphanum("10") assert alphanum("9")<alphanum("10") assert alphanum("A1")<alphanum("A10") assert alphanum("A9")<alphanum("A10") assert alphanum("AA1")<alphanum("AA10") assert alphanum("AA9")<alphanum("AA10") assert alphanum("1")<alphanum("A1") assert alphanum("A1")<alphanum("AA1") assert alphanum("B1")<alphanum("AA1") ================ > mais le dernier test échoue : pouquoi B1 serait-il inférieur à AA1 ? dans l'ordre alphabétique normal, B est après AA
A+ Pierre
Bonjour Pierre,
Le fait que B soit avant AA vient du contexte d'utilisation. Je me fais un utilitaire pour manipuler des données de pattes de composants électroniques. Les pattes sont numérotées purement numériquement pour les composants qui ont des pattes sur le pourtour. Pour les composants qui ont des pattes sous la forme d'une grille répartie sous le boitier, la numérotation se fait sous la forme colonne/ligne avec des lettres pour les colonnes et des chiffres pour les lignes. Les lettres sont dans l'ordre A, B, C... AA, AB, AC.. BA, BB, BC...
Dans mon utilitaire, je veux les afficher dans une liste triée. Il me faut donc une fonction de comparaison adaptée à cet ordre.
Je suis arrivé à ça : e1 = re.findall(r'(d+|D+)', self.pins[item1].pin_name) e2 = re.findall(r'(d+|D+)', self.pins[item2].pin_name) for a,b in zip(e1, e2) : if len(a) > len(b) : return 1 elif len(a) < len(b) : return -1 else : r = cmp(a, b) if r : return r
Je vais remplacer les expression régulières par rstrip() et int(). J'oublie toujours que la chaine passée à rstrip() est une liste de caractères à supprimer et non pas la chaine à supprimer.
Merci
Nicolas
On 22 oct, 14:46, NicolasP<nicol...@aaton.com> wrote:
Bonjour,
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique".
Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique.
Soit :
"1"< "10"
"9"< "10"
"A1"< "A10"
"A9"< "A10"
"AA1"< "AA10"
"AA9"< "AA10"
"1"< "A1"
"A1"< "AA1"
"B1"< "AA1"
...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
assert alphanum("1")<alphanum("10")
assert alphanum("9")<alphanum("10")
assert alphanum("A1")<alphanum("A10")
assert alphanum("A9")<alphanum("A10")
assert alphanum("AA1")<alphanum("AA10")
assert alphanum("AA9")<alphanum("AA10")
assert alphanum("1")<alphanum("A1")
assert alphanum("A1")<alphanum("AA1")
assert alphanum("B1")<alphanum("AA1")
================ >
mais le dernier test échoue : pouquoi B1 serait-il inférieur à AA1 ?
dans l'ordre alphabétique normal, B est après AA
A+
Pierre
Bonjour Pierre,
Le fait que B soit avant AA vient du contexte d'utilisation.
Je me fais un utilitaire pour manipuler des données de pattes de composants électroniques.
Les pattes sont numérotées purement numériquement pour les composants qui ont des pattes sur le pourtour.
Pour les composants qui ont des pattes sous la forme d'une grille répartie sous le boitier, la numérotation se fait sous la forme colonne/ligne avec des lettres pour les colonnes et des chiffres pour les lignes. Les lettres sont dans l'ordre A, B, C... AA, AB, AC.. BA, BB, BC...
Dans mon utilitaire, je veux les afficher dans une liste triée. Il me faut donc une fonction de comparaison adaptée à cet ordre.
Je suis arrivé à ça :
e1 = re.findall(r'(d+|D+)', self.pins[item1].pin_name)
e2 = re.findall(r'(d+|D+)', self.pins[item2].pin_name)
for a,b in zip(e1, e2) :
if len(a) > len(b) :
return 1
elif len(a) < len(b) :
return -1
else :
r = cmp(a, b)
if r :
return r
Je vais remplacer les expression régulières par rstrip() et int(). J'oublie toujours que la chaine passée à rstrip() est une liste de caractères à supprimer et non pas la chaine à supprimer.
Je cherche à faire une fonction de comparaison de chaine de caractères pour un tri "alpha-numérique". Les chaines sont composées d'une partie alphabétique(facultative) et d'une partie numérique. Soit : "1"< "10" "9"< "10" "A1"< "A10" "A9"< "A10" "AA1"< "AA10" "AA9"< "AA10"
"1"< "A1" "A1"< "AA1" "B1"< "AA1" ...
Clairement, il faut séparer la partie alphabétique et la partie numérique et traiter la partie numérique comme un nombre et non pas comme une chaine.
assert alphanum("1")<alphanum("10") assert alphanum("9")<alphanum("10") assert alphanum("A1")<alphanum("A10") assert alphanum("A9")<alphanum("A10") assert alphanum("AA1")<alphanum("AA10") assert alphanum("AA9")<alphanum("AA10") assert alphanum("1")<alphanum("A1") assert alphanum("A1")<alphanum("AA1") assert alphanum("B1")<alphanum("AA1") ================ > mais le dernier test échoue : pouquoi B1 serait-il inférieur à AA1 ? dans l'ordre alphabétique normal, B est après AA
A+ Pierre
Bonjour Pierre,
Le fait que B soit avant AA vient du contexte d'utilisation. Je me fais un utilitaire pour manipuler des données de pattes de composants électroniques. Les pattes sont numérotées purement numériquement pour les composants qui ont des pattes sur le pourtour. Pour les composants qui ont des pattes sous la forme d'une grille répartie sous le boitier, la numérotation se fait sous la forme colonne/ligne avec des lettres pour les colonnes et des chiffres pour les lignes. Les lettres sont dans l'ordre A, B, C... AA, AB, AC.. BA, BB, BC...
Dans mon utilitaire, je veux les afficher dans une liste triée. Il me faut donc une fonction de comparaison adaptée à cet ordre.
Je suis arrivé à ça : e1 = re.findall(r'(d+|D+)', self.pins[item1].pin_name) e2 = re.findall(r'(d+|D+)', self.pins[item2].pin_name) for a,b in zip(e1, e2) : if len(a) > len(b) : return 1 elif len(a) < len(b) : return -1 else : r = cmp(a, b) if r : return r
Je vais remplacer les expression régulières par rstrip() et int(). J'oublie toujours que la chaine passée à rstrip() est une liste de caractères à supprimer et non pas la chaine à supprimer.