dplyr с 0,4 реализовал все те объединения, в том числе external_join, но стоит отметить, что для первых нескольких релизов он использовал не для того, чтобы предлагать внешний_join, и в результате было много действительно плохой взломанный обходной код пользователя, плавающий вокруг (вы все еще можете найти это в ответах SO и Kaggle с того периода).
Основные моменты выделения :
v0.1.3 (4/2014)
Обходные решения для комментариев хайли в этой проблеме:
Вы можете использовать следующий класс MyFloat
вместо встроенного класса float
.
def _remove_leading_zero(value, string):
if 1 > value > -1:
string = string.replace('0', '', 1)
return string
class MyFloat(float):
def __str__(self):
string = super().__str__()
return _remove_leading_zero(self, string)
def __format__(self, format_string):
string = super().__format__(format_string)
return _remove_leading_zero(self, string)
С помощью этого класса вам придется использовать функцию str.format
вместо оператора модуля ( %
) для форматирования. Ниже приведены некоторые примеры:
>>> print(MyFloat(.4444))
.4444
>>> print(MyFloat(-.4444))
-.4444
>>> print('some text {:.3f} some more text',format(MyFloat(.4444)))
some text .444 some more text
>>> print('some text {:+.3f} some more text',format(MyFloat(.4444)))
some text +.444 some more text
Если вы также хотите заставить оператор модуля (%
) класса str
вести себя одинаково, тогда вам придется переопределить __mod__
метод класса str
путем подкласса класса. Но это будет не так просто, как переопределить метод __format__
класса float
, так как в этом случае отформатированное число с плавающей точкой может присутствовать в любой позиции в результирующей строке.
[Примечание: Все приведенные выше коды написаны на Python3. Вам также придется переопределить __unicode__
в Python2, а также изменить вызовы super
.]
Используйте .lstrip()
, после использования форматирования строки для преобразования в строку:
>>> k = .1827412
>>> print ("%.4f"%(k)).lstrip('0')
.1827
>>>
.lstrip()
можно использовать для удаления любого из ведущих символов строки:
>>> k = 'bhello'
>>> print k.lstrip('b')
hello
>>> print k.lstrip('bhel')
o
>>> print k.lstrip('bel')
hello
>>>
string.lstrip (s [, chars])
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; ; & nbsp; & nbsp; & nbsp; Возвращает копию строки с удаленными ведущими символами
Я бы лучше читал и прост, чем что-либо еще: Давайте обрабатывать знак и цифры независимо. И немного в строке, если утверждение никогда никого не повредит.
k = -.1337
"".join( ["-" if k < 0 else "", ("%.4f" % abs(k)).lstrip('0')] )
+
, а не используете join
. «Конечно, вам понадобится скобка вокруг логики знака.
– jrennie
15 May 2014 в 09:11
Насколько мне нравятся милые трюки регулярных выражений, я думаю, что простая функция - это лучший способ сделать это:
def formatFloat(fmt, val):
ret = fmt % val
if ret.startswith("0."):
return ret[1:]
if ret.startswith("-0."):
return "-" + ret[2:]
return ret
>>> formatFloat("%.4f", .2)
'.2000'
>>> formatFloat("%.4f", -.2)
'-.2000'
>>> formatFloat("%.4f", -100.2)
'-100.2000'
>>> formatFloat("%.4f", 100.2)
'100.2000'
Это имеет смысл быть понятным, частично потому, что startswith
это простое совпадение строк, а не регулярное выражение.
Поскольку мы рассматриваем только> -1 для & lt; 1, тогда будет работать следующее редактирование.
import re
re.sub(r"0+\.", ".", %0.4f" % k)
Это будет поддерживать знак, только удаляя цифру слева от десятичной.
import re
re.sub("^(\-?)0\.", r'\1.', "%.4f" % k)
Это короткий, простой и я не могу найти сценарий, для которого он не работает.
Примеры:
>>> import re
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 0)
'.0000'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 0.1337)
'.1337'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 1.337)
'1.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -0)
'.0000'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -0.1337)
'-.1337'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -1.337)
'-1.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % 10.337)
'10.3370'
>>> re.sub("^(\-?)0\.", r'\1.', "%.4f" % -10.337)
'-10.3370'
Редактировать: Если вы рассматривают только числа> -10 и & lt; 10 Будет работать следующее:
("%.4f", k).replace('0.', '.')
re.sub
и теперь выполняется сопоставление скобок
– nettux443
14 May 2014 в 01:07
Вот еще один способ:
>>> ("%.4f" % k).lstrip('0')
'.1337'
Он немного более общий, чем [1:]
, поскольку он также работает с числами> = 1.
Ни один из методов не корректно обрабатывает отрицательные номера, однако. В этом отношении лучше:
>>> re.sub('0(?=[.])', '', ("%0.4f" % -k))
'-.1337'
Не особенно изящно, но сейчас я не могу придумать лучшего метода.
re.sub(r'^(-?)0(?=\.)', r'\1', ...)
)
– musicinmybrain
12 May 2014 в 14:47
Один жизнеспособный вариант, который работает без регулярного выражения и с отрицательными значениями больше 10
k = -.1337
("%.4f" % k).replace("-0","-").lstrip("0")
.
является метасимволом регулярного выражения. Вы понимаете, что произойдет, если k
- -100.1337
?
– devnull
13 May 2014 в 20:17
-10.1337
для приведенного выше примера.
– devnull
13 May 2014 в 21:26
Я удивлен, что никто не предложил более математический способ сделать это:
n = 0.123456789
'.%d' % (n*1e4)
Мне гораздо приятнее. :)
Но интересно, что ваш самый быстрый.
$ python -mtimeit '".%d" % (0.123456789*1e4)'
1000000 loops, best of 3: 0.809 usec per loop
$ python -mtimeit '("%.4f"%(0.123456789)).lstrip("0")'
1000000 loops, best of 3: 0.209 usec per loop
$ python -mtimeit '("%.4f"%(0.123456789))[1:]'
10000000 loops, best of 3: 0.0723 usec per loop
Строка str.format () стандартной библиотеки Python может использоваться для генерации преобразования строки значения float. Затем можно манипулировать строкой, чтобы сформировать конечный результат для положительного или отрицательного числа.
n = -.1234567890
print('{0}'.format('-' if n < 0 else '') + ('{:0.4}'.format(n).split('-')[1 if n < 0 else 0].lstrip('0')))
remove_leading_zeros
remove_all_zeros
. Кажется неуклюжим и неправильным. – hobs 25 February 2016 в 01:22string.replace('0', '', 1)
удалит только первый ноль, а условиеif 1 > value > -1
будет убедиться, что оно применяется только тогда, когда строка находится в форме0.<some digits>
. – Debanshu Kundu 25 February 2016 в 11:28'.402'.replace('0', '', 1)
- & gt;.42
. Ваш код будет работать для всех строк, созданных__str__
наfloat
s, как определено в настоящий момент, но ваш код является хрупким (неуклюжим). Это не идемпотент. И это невозможно для будущего.lstrip
намного более кратким и надежным (идемпотентным и перспективным). Ваша операцияreplace
не может применяться более одного раза. И если ваш конкретный тип номера не ограничивал способ создания python встроенных поплавков, хорошо ... – hobs 26 February 2016 в 04:32