Tengo esta linea

HL1110 / 1110R / 1112 / 1112R / MFC1810 / 1810R / 1815 / 1815R / DCP1510 / 1510R / 1512 / 1512R

Como puede ver, algunos de ellos tienen HL o un par de otras letras, lo que significa que 1110R también es de la serie HL,

Estoy tratando de dividir la línea con "/" y luego buscar cadenas, pero luego, necesito apuntar HL desde 1110, ¿cómo lo hago? Verificar con isinstance (x, str) me da verdadero con ambos valores (H o 1), entonces, ¿cómo los separo como cadenas y dígitos?

-2
ipsissimus 28 ago. 2014 a las 02:00

5 respuestas

La mejor respuesta
>>> from itertools import groupby
>>> s = "HL1110/1110R/1112/1112R/MFC1810/1810R/1815/1815R/DCP1510/1510R/1512/1512R"
>>> for item in s.split("/"):
...     print ["".join(g) for k,g in groupby(item, str.isdigit)]
... 
['HL', '1110']
['1110', 'R']
['1112']
['1112', 'R']
['MFC', '1810']
['1810', 'R']
['1815']
['1815', 'R']
['DCP', '1510']
['1510', 'R']
['1512']
['1512', 'R']
2
John La Rooy 27 ago. 2014 a las 22:41

re puede dividirlos en listas de entradas y cadenas:

import re

s = "HL1110/1110R/1112/1112R/MFC1810/1810R/1815/1815R/DCP1510/1510R/1512/1512R"

ints  = re.findall("\d+",s) # one or more digits
st = re.findall("[A-Z]+",s) # one or more uppercase  letters 

print ints,st
['1110', '1110', '1112', '1112', '1810', '1810', '1815', '1815', '1510', '1510', '1512', '1512'] ['HL', 'R', 'R', 'MFC', 'R', 'R', 'DCP', 'R', 'R']

Si quieres una lista de entradas:

print map(int,ints)
[1110, 1110, 1112, 1112, 1810, 1810, 1815, 1815, 1510, 1510, 1512, 1512]
0
Padraic Cunningham 27 ago. 2014 a las 22:11

Usaría expresiones regulares para separar el componente de la serie:

from pprint import pprint
import re

line = 'HL1110/1110R/1112/1112R/MFC1810/1810R/1815/1815R/DCP1510/1510R/1512/1512R'

result = {}
series = ''
for item in line.split('/'):
  match = re.match(r'(\D*)(.*)', item)
  if not match:
    print '%s: bad form?'%item
    continue
  i,j = match.groups()
  if i:
    series = i
  result.setdefault(series, []).append(j)
pprint (result)

Otra forma, usando re.findall() en lugar de re.match():

from pprint import pprint
import re

line = 'HL1110/1110R/1112/1112R/MFC1810/1810R/1815/1815R/DCP1510/1510R/1512/1512R'

series = None
result = {}
for maybe_series, item in re.findall('([A-Z]*)([^/]+)', line):
  series = maybe_series or series
  result.setdefault(series, []).append(item)
pprint (result)
2
Robᵩ 27 ago. 2014 a las 22:19

Puede separarse usando isdigit(). Por ejemplo, usando la comprensión de la lista:

>>> s = "HL1110/1110R/1112/1112R/MFC1810/1810R/1815/1815R/DCP1510/1510R/1512/1512R"
>>> [i for i in s.split('/')]
['HL1110', '1110R', '1112', '1112R', 'MFC1810', '1810R', '1815', '1815R', 'DCP1510', '1510R', '1512', '1512R']
>>> [i for i in s.split('/') if i.isdigit()]
['1112', '1815', '1512']
>>> [i for i in s.split('/') if not i.isdigit()]
['HL1110', '1110R', '1112R', 'MFC1810', '1810R', '1815R', 'DCP1510', '1510R', '1512R']

Usar filter es equivalente:

>>> filter(lambda x:x.isdigit(), s.split('/'))
['1112', '1815', '1512']
>>> filter(lambda x:not x.isdigit(), s.split('/'))
['HL1110', '1110R', '1112R', 'MFC1810', '1810R', '1815R', 'DCP1510', '1510R', '1512R']

Alternativamente, si solo desea algunas de las cadenas, puede usar una condición diferente en la parte if. Para tener solo cadenas con 'R' o 'HL', simplemente cambie la condición if:

>>> [i for i in s.split('/') if ('R' in i) or ('HL' in i)]
['HL1110', '1110R', '1112R', '1810R', '1815R', '1510R', '1512R']
3
fredtantini 27 ago. 2014 a las 22:20

Las cadenas tienen un muy buen método isdigit que puedes usar.

>>> 'H'.isdigit()
False
>>> '1'.isdigit()
True
>>> '10'.isdigit()
True
4
mgilson 27 ago. 2014 a las 22:01