Как я могу улучшить этот код? - PullRequest
4 голосов
/ 05 июля 2010
# 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

Что я делаю, округляя числа до ближайшего, ну, заполненного нулями значения?Я не уверен, как это будет называться.Но в основном я хочу 83 -> 100, 1 -> 1, 1350 -> 10000, 100 -> 100. Я пытался использовать функцию round (), но не смог заставить ее делать то, что хотел.

Это делает это, но я думал, что это может быть написано в меньшем количестве строк.

Ответы [ 7 ]

11 голосов
/ 05 июля 2010

Я бы сделал это математически:

from math import ceil, log10
int(pow(10, ceil(log10(abs(x or 0.1)))))
3 голосов
/ 05 июля 2010
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

Он делает что-то разумное с негативами, но не уверен, что именно такое поведение вы хотите или нет.

1 голос
/ 05 июля 2010
>>> x = 12345.678
>>> y = round(x)
>>> round(10 * y, -len(str(y)))
100000
1 голос
/ 05 июля 2010

мне нужно, чтобы оно было 1350/10000 = 0,135, поэтому оно находится в диапазоне [0, 1].

Почему вы не сказали об этом изначально?

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

Если вам не нужны цифры для чего-то еще?

0 голосов
/ 05 июля 2010
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]
0 голосов
/ 05 июля 2010

Ваш исходный код был близок, и его было легче прочитать, чем какое-то сжатое выражение. Проблема с вашим кодом - пара незначительных ошибок: инициализация new_value каждый раз при первоначальном сканировании, а не только один раз; и заменив max_list вычисленным скаляром, зацикливая его как список.

В последней строке вы должны указать:

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

но вы удалили индекс массива, который заменил бы список одним значением. На второй итерации цикла ваш Python выдаст исключение из-за недопустимого индекса в не список.

Поскольку ваш код развивает все новые и новые значения new_value по мере его продвижения, я рекомендую вам не заменять элементы списка во время первого сканирования. Сделайте второе сканирование, как только вы вычислите окончательное значение для 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]"

Обратите внимание, что я должен был инициализировать new_value, как если бы это было значение с плавающей запятой, чтобы оно приводило к частным числам с плавающей запятой. Существуют альтернативные способы сделать это, например, использовать float(max_list[i]) для получения значения для нормализации. Исходное вычисление new_value начиналось с каждого элемента, поэтому ваш пример вернул бы new_value == 100, потому что это основывалось на последнем элементе в списке ввода, который равен 100.

0 голосов
/ 05 июля 2010

Псевдокод:

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