2010-07-05 11 views
4
# max_list = [83, 1350, 1, 100] 
for i in range(len(max_list)): 
    new_value = 1 
    while new_value < max_list[i]: 
      new_value *= 10 
    max_list = new_value 

Qu'est-ce que je fais est d'arrondir les nombres jusqu'à la valeur la plus proche, uhm, zéro rempli? Je ne suis pas sûr de ce que ça s'appellerait. Mais fondamentalement, je veux 83 -> 100, 1 -> 1, 1350 -> 10000, 100 -> 100. J'ai essayé d'utiliser la fonction round() mais je n'ai pas réussi à faire ce que je voulais.Comment puis-je améliorer ce code?

Cela le fait mais je pensais qu'il pourrait être écrit en moins de lignes.

+0

Il devrait être 1350 -> 1000. –

+0

Non, je veux que ça passe à 10000. Je vais diviser les valeurs par ces nombres plus tard. J'ai besoin qu'il soit de 1350/10000 = 0.135 donc c'est dans la gamme [0, 1]. – iceburn

+0

Vous voulez tous les nombres normalisés à la même puissance de dix, non? Vous n'avez pas besoin d'expressions différentes pour 'new_value', vous avez besoin de deux passes. –

Répondre

11

que je le ferais mathématiquement:

from math import ceil, log10 
int(pow(10, ceil(log10(abs(x or 0.1))))) 
+0

J'utiliserais 'pow (10, ceil (abs (log10 (x))))' pour le cas d'une entrée négative. – Femaref

+0

Qu'en est-il de zéro? –

+3

+1, Regardez-vous, apportant l'intelligence où tout le monde a apporté le traitement de chaîne :) Et zéro est un cas particulier trivial. – Stephen

3
def nextPowerOfTen(x): 
    if x in [0, 1]: 
    return x 
    elif x < 1: 
    return -nextPowerOfTen(abs(x)) 
    else: 
    return 10**len(str(int(x) - 1)) 

>>> nextPowerOfTen(83) 
100 
>>> nextPowerOfTen(1350) 
10000 
>>> nextPowerOfTen(1) 
1 
>>> nextPowerOfTen(100) 
100 
>>> nextPowerOfTen(0) 
0 
>>> nextPowerOfTen(-1) 
-1 
>>> nextPowerOfTen(-2) 
-10 

Il fait quelque chose de sensible avec des négatifs, pas sûr si c'est le comportement que vous voulez ou non.

+0

échoue sur les puissances de 10. –

+0

Correction d'un échec sur les puissances de 10 – fmark

1

J'ai besoin qu'il soit 1350/10000 = 0.135 donc c'est dans la gamme [0, 1].

Pourquoi ne l'avez-vous pas dit initialement?

new_val = float("0." + str(old_val)) 

À moins que vous n'ayez besoin des chiffres pour quelque chose d'autre?

+1

vous voulez probablement utiliser float(), pas int() – Bwmat

+0

J'utilise aussi des points flottants - j'ai oublié de le mentionner - donc je pense que je devrais supprimer le séparateur. mais cela semble que ça va marcher – iceburn

+0

Est-ce que cela ne échoue pas pour 1, '1-> 0.1' devrait être' 1-> 1'? – Stephen

1
>>> x = 12345.678 
>>> y = round(x) 
>>> round(10 * y, -len(str(y))) 
100000 
+0

ne fonctionne pas pour les points flottants si. J'ai oublié de mentionner que désolé – iceburn

+0

édité et corrigé. –

0

pseudocode:

div = input != 1 ? power(10,truncate(log10(abs(input))) + 1) : 1; 
percent = input/div; 
0

Votre code d'origine était proche, et de lire plus facilement que une expression laconique. Le problème avec votre code est un couple d'erreurs mineures: initialisation new_value chaque fois dans l'analyse initiale, plutôt qu'une seule fois; et en remplaçant le max_list par un scalaire calculé tout en le bouclant en tant que liste.

Sur la dernière ligne, vous devez avoir l'intention:

max_list[i] = float(max_list[i])/new_value 

mais vous avez laissé tomber l'index du tableau, qui remplacerait la liste avec une valeur unique. Lors de la deuxième itération de la boucle, votre Python donnerait une exception en raison de l'index invalide dans une non-liste. Comme votre code développe des valeurs de plus en plus grandes de new_value à mesure qu'il progresse, je vous recommande de ne pas remplacer les éléments de la liste lors de la première analyse. Faire une deuxième analyse une fois que vous calculez une valeur finale pour new_value:

max_list = [83, 1350, 1, 100] 

# Calculate the required "normalizing" power-of-ten 
new_value = 1.0 
for i in range(len(max_list)): 
    while new_value < max_list[i]: 
     new_value *= 10.0 

# Convert the values to fractions in [0.0, 1.0] 
for i in range(len(max_list)): 
    max_list[i] = max_list[i]/new_value 

print max_list 
# "[0.0083000000000000001, 0.13500000000000001, 0.0001, 0.01]" 

Notez que je requis pour initialiser new_value comme si elle était une valeur à virgule flottante, afin qu'il entraînerait quotients à virgule flottante. Il existe d'autres manières de procéder, par exemple en utilisant float(max_list[i]) pour récupérer la valeur pour la normalisation. Le calcul initial de new_value commençait sur chaque élément, de sorte que votre exemple retournerait parce que cela a été basé sur l'élément final dans la liste d'entrée, qui est 100.

+0

max_list a le maximum de chaque colonne dans un fichier. après avoir changé les valeurs, je divise chaque élément pour son maximum respectif, par exemple si la première ligne de mon fichier est: 10, 10, 20, 30 et mes maximums sont 10, 100, 100, 1000, je vais avoir 1, 0.1, 0,2, 0,03 comme nouvelle première ligne. le code que j'ai posté ne montre qu'une partie de ce que je fais, qui prend les maximums et les arrondit – iceburn

+0

Dans ce cas, la seule chose qui ne va pas avec votre code original est le commentaire "dernière ligne" que j'ai fait. :) –

0
from math import ceil, log10 

# works for floats, too. 
x = [83, 1350, 1, 100, 12.75] 
y = [10**ceil(log10(el)) for el in x] 

# alt list-comprehension if integers needed 
# y = [int(10**ceil(log10(el))) for el in x]