Tengo una secuencia de números como:

1234
5678
778899

Quiero convertirlos en un formulario donde comiencen desde el número más bajo posible

Ejemplo:

5678 would be 1234
778899 would be 112233
2452 would be 1231

Traté de hacer:

index = 0
digit = 1
newCode = []
newCode.append(digit)

while index != len(codice)-1:
    index += 1

    if code[index] == code[index-1]:
        newCode.append(digit)

    else:
        digit += 1
        newCode.append(digit) 

Pero convierte números como 5675 a 1234, por lo que no funciona. ¿Hay una mejor manera de hacer esto y qué estoy haciendo mal?

5
John Poe 29 oct. 2017 a las 20:54

6 respuestas

La mejor respuesta

Esto se puede hacer con los diccionarios:

Editar: Entonces podría haber malinterpretado la pregunta. A partir de los casos de ejemplo, supuse que significaba convertir el primer dígito que aparecía en 1, el segundo en 2, etc.

x = "5512"
function = {}
count = 1
output = ""

for digit in x:
     if digit in function:
         output += function[digit]
     else:
         function[digit] = str(count)
         count += 1
         output += function[digit]

print(output)
#Outputs 1123 (5->1, 1->2, 2->3)
7
wjmccann 29 oct. 2017 a las 18:17
t = {}
int(''.join(t.setdefault(d, str(len(t) + 1)) for d in str(n)))

Demo:

>>> for n in 5678, 778899, 2452:
        t = {}
        print(n, '->', int(''.join(t.setdefault(d, str(len(t) + 1)) for d in str(n))))

5678 -> 1234
778899 -> 112233
2452 -> 1231
7
Stefan Pochmann 29 oct. 2017 a las 18:21

TL; DR

El siguiente código funciona para sus requisitos, haciendo uso de dictionary.

out = []
for n in num:
    digits = {}
    last_digit = 1

    new_num = ''

    #assign new values
    for s in str(n):                       #go through digits of number
        if digits.get(s, None) == None :    #if new digit not assigned
                digits[s] = str(last_digit)   #assign
                new_num += str(last_digit)
                last_digit += 1
        else :
                new_num += digits[s]         #get the val

    out.append(int(new_num))


print(out)

# valores del controlador:

IN : num = [1234, 5678, 778899, 2452]
OUT : [1234, 1234, 112233, 1231]
1
Kaushik NP 29 oct. 2017 a las 18:15

Solución de una línea usando .index():

Después de haber sido engañado acerca de lo que se intentaba lograr, esta es mi segunda respuesta, que creo que cumple los requisitos de manera bastante sucinta.

from collections import OrderedDict
def transform(n):
    s = str(n)
    return int(''.join(str(list(OrderedDict.fromkeys(s)).index(e)+1) for e in s))

Y algunos ejemplos:

>>> transform(5678)
1234
>>> transform(778899)
112233
>>> transform(2452)
1231

El code aprovecha el hecho de que index esencialmente le dará el value de un digit directamente, sin la necesidad de un dictionary.

Primero, eliminamos el duplicates del string usando OrderedDict.fromkeys(). Luego de esto, podemos verificar el index de cada digit para obtener su value. Necesitamos agregar 1 a index ya que el primero debe ser 1 (no 0).

2
Joe Iddon 29 oct. 2017 a las 18:35

Solo verifica si el dígito es igual al último dígito, pero eso no funciona, por ejemplo, 2452. Debe realizar un seguimiento de todos los dígitos pasados, utilizando p. un diccionario, como en @wjmccann answer .

Sin embargo, puede hacer esto un poco más corto combinando un {{X0 }} con un count . defaultdict memorizará dígitos ya vistos, y count proporciona valores para los nuevos.

import itertools, collections, functools

def convert(n):
    d = collections.defaultdict(functools.partial(next, itertools.count(1)))
    return int(''.join(str(d[x]) for x in str(n)))

print(convert(5678))   # 1234
print(convert(778899)) # 112233
print(convert(2452))   # 1231

O incluso más corto, como se sugiere en comentarios:

def convert(n):
    d = collections.defaultdict(list("987654321").pop)
    return int(''.join(d[x] for x in str(n)))

Esto nuevamente usa defaultdict, pero usa pop de una lista de dígitos como la función de fábrica, eliminando elementos del final de la lista ya que se necesitan nuevos dígitos.

3
tobias_k 29 oct. 2017 a las 20:30

If code [index] == code [index-1]:

NewCode.append (1)

    you using digit variable in both place..

Más:

Dígito + = 1
newCode.append (dígito)

0
Naveen Roy 29 oct. 2017 a las 18:12