2010-07-16 5 views
12

플로트가 포함 된 목록과 복잡한 구조가 있습니다. 인쇄 할 때 10 진수가 많은 부동 소수점을 볼 수 있지만 인쇄 할 때 모두 필요하지는 않습니다. 그래서 float가 인쇄 될 때 맞춤 형식 (예 : 2 또는 3 소수)을 정의하고 싶습니다.기본 float 인쇄 형식을 변경하십시오.

10 진수가 아닌 부동 소수점을 사용해야합니다. 또한, 나는자를자를 수 없다.

기본 동작을 변경하는 방법이 있습니까?

답변

7

이그나시오 (Ignacio)가 말했듯이, C 타입을 monkeypatch하는 것.

그러나 C 언어에 익숙하다면 Python 인터프리터 소스 코드를 직접 수정 한 다음 사용자 정의 솔루션으로 다시 컴파일 할 수 있습니다. 일단 목록에 대한 표준 행동 중 하나를 수정하고 나면 그것은 온건 한 고통이었습니다.

난 당신은 단지 "%0.2f"의 printf 표기와 함께 수레를 인쇄로, 더 나은 해결책을 찾을 제안 : 파이썬 3.1

for item in mylist: 
    print '%0.2f' % item, 

또는

print " ".join('%0.2f' % item for item in mylist) 
+0

문제는 내가 목록 내부에 떠 있었고, 인쇄 할 때 (목록) 나는 그것에 대한 통제권이 없다는 것입니다. (이것은 다른 객체, btw에도 적용됩니다). C가 알고 있듯이 소스 코드를 수정하는 것이 가능하지만 생각했던 것과 정확히 같지 않습니다. 감사. – AkiRoss

+0

@AkiRoss : 그럼 당신이 고쳐주고 싶은 것은 수레가 아니라 목록입니다. –

+0

@AkiRoss, 더 많은 컨트롤을 원하면 개별적으로 항목을 인쇄하십시오. –

3

아니요. 수정하려면 float.__str__()이 필요하므로 C 유형을 Monkeypatch 할 수 없습니다. 문자열 보간이나 서식을 대신 사용하십시오.

+0

실제로, 'float .__ repr__'을 수정해야합니다.'str'은 12 자리 유효 숫자 만 사용합니다. – dan04

1
>>> a = 0.1 
>>> a 
0.10000000000000001 
>>> print a 
0.1 
>>> print "%0.3f" % a 
0.100 
>>> 
바로 대화 형 프롬프트에서 a를 입력하여 볼 때 repr(a)이 (17 자리 숫자를 줄 것이다 Python docs에서

,하지만 str(a)은 (당신이 그것을 인쇄 할 때 자동으로 수행) (12)

편집 반올림 : 대부분의 당신은 허용되지 않습니다 기본적인 해킹 솔루션 ... 당신은 그래 ... 그래서, 비록 자신의 클래스를 사용할 필요가 .

>>> class myfloat(float): 
...  def __str__(self): 
...    return "%0.3f" % self.real 
>>> b = myfloat(0.1) 
>>> print repr(b) 
0.10000000000000001 
>>> print b 
0.100 
>>> 
0

업그레이드. 필요한 것보다 더 많은 자릿수를 사용하지 않습니다. 당신이 C 언어를 사용하는 경우

Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 0.1 
0.1 
+0

이미 사용 중입니다. 그게 중요한 것은 아니지만 팁에 감사드립니다. – AkiRoss

-1

, 당신도, 예를 그렇게 #define 또는 "%*.*f"을 사용할 수 있습니다

printf("%*.*f",4,2,variable); 
+1

그는 명시 적으로 파이썬 태그를 사용하고 있으므로 C를 사용하지 않습니다. – Bruce

2

오늘이 문제가 발생하여 다른 해결책을 찾았습니다. 프린트 할 때의 모습에 대해 걱정이된다면 stdout 파일 객체를 write()가 호출 될 때 float처럼 보이는 것을 검색하여 자신의 형식으로 대체 할 수있는 custom 객체로 대체 할 수 있습니다. 그들.

class ProcessedFile(object): 

    def __init__(self, parent, func): 
     """Wraps 'parent', which should be a file-like object, 
     so that calls to our write transforms the passed-in 
     string with func, and then writes it with the parent.""" 
     self.parent = parent 
     self.func = func 

    def write(self, str): 
     """Applies self.func to the passed in string and calls 
     the parent to write the result.""" 
     return self.parent.write(self.func(str)) 

    def writelines(self, text): 
     """Just calls the write() method multiple times.""" 
     for s in sequence_of_strings: 
      self.write(s) 

    def __getattr__(self, key): 
     """Default to the parent for any other methods.""" 
     return getattr(self.parent, key) 

if __name__ == "__main__": 
    import re 
    import sys 

    #Define a function that recognises float-like strings, converts them 
    #to floats, and then replaces them with 1.2e formatted strings. 
    pattern = re.compile(r"\b\d+\.\d*\b") 
    def reformat_float(input): 
     return re.subn(pattern, lambda match: ("{:1.2e}".format(float(match.group()))), input)[0] 

    #Use this function with the above class to transform sys.stdout. 
    #You could write a context manager for this. 
    sys.stdout = ProcessedFile(sys.stdout, reformat_float) 
    print -1.23456 
    # -1.23e+00 
    print [1.23456] * 6 
    # [1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00, 1.23e+00] 
    print "The speed of light is 299792458.0 m/s." 
    # The speed of light is 3.00e+08 m/s. 
    sys.stdout = sys.stdout.parent 
    print "Back to our normal formatting: 1.23456" 
    # Back to our normal formatting: 1.23456 

그것은 당신이 단지 문자열로 숫자를 가하고있어, 결국 당신은 아마 어딘가에 파일의 일종에 해당 문자열을 쓰고 싶은 것,하고 해당 파일을 포장 할 수있을 경우 좋지 않습니다 위의 개체. 분명히 약간의 성능 오버 헤드가 있습니다.

공정한 경고 :이 기능은 Python 3에서 테스트하지 않았지만 제대로 작동하는지는 알 수 없습니다.

관련 문제