2010-07-16 34 views
12

Tôi đã liệt kê một số danh sách và cấu trúc phức tạp hơn có chứa phao. Khi in chúng, tôi thấy các phao có nhiều chữ số thập phân, nhưng khi in, tôi không cần tất cả chúng. Vì vậy, tôi muốn xác định định dạng tùy chỉnh (ví dụ: 2 hoặc 3 số thập phân) khi phao được in.Thay đổi định dạng in nổi mặc định

Tôi cần sử dụng phao và không phải thập phân. Ngoài ra, tôi không được phép cắt ngắn/vòng phao.

Có cách nào để thay đổi hành vi mặc định không?

Trả lời

7

bạn không được phép để loại khỉ giống C, như Ignacio nói.

Tuy nhiên, nếu bạn bị ép khủng khiếp khi làm như vậy và bạn biết một số C, bạn có thể tự sửa đổi mã nguồn trình thông dịch Python, sau đó biên dịch lại thành giải pháp tùy chỉnh. Khi tôi sửa đổi một trong những hành vi tiêu chuẩn cho danh sách và nó chỉ là một cơn đau vừa phải.

Tôi đề nghị bạn tìm thấy một giải pháp tốt hơn, chẳng hạn như chỉ in nổi với các ký hiệu "%0.2f" printf:

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

hoặc

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

Vấn đề là tôi đã nổi trong danh sách, và khi tôi in (danh sách) tôi không kiểm soát được điều đó. (Điều này cũng áp dụng cho các đối tượng khác, btw). Sửa đổi mã nguồn là khả thi như tôi biết C, nhưng không phải là chính xác những gì tôi đã nghĩ đến. Cảm ơn. – AkiRoss

+0

@AkiRoss: Vì vậy, sau đó những gì bạn muốn sửa chữa là danh sách, không phải là nổi ... –

+0

@AkiRoss, nếu bạn muốn kiểm soát nhiều hơn chỉ in các mục riêng lẻ. –

3

Không, vì điều đó sẽ yêu cầu sửa đổi float.__str__(), nhưng bạn không được phép sử dụng loại khỉ C. Thay vào đó, hãy sử dụng định dạng hoặc nội suy chuỗi.

+0

Thực ra, nó sẽ yêu cầu sửa đổi 'float .__ repr__'.'str' chỉ sử dụng 12 chữ số có nghĩa. – dan04

1
>>> a = 0.1 
>>> a 
0.10000000000000001 
>>> print a 
0.1 
>>> print "%0.3f" % a 
0.100 
>>> 

Từ Python docs, repr(a) sẽ cung cấp cho 17 chữ số (như đã thấy bởi chỉ cần gõ a tại dấu nhắc tương tác, nhưng str(a) (tự động thực hiện khi bạn in nó) làm tròn đến 12.

Edit: Hầu hết các giải pháp cơ bản Hack ... bạn phải sử dụng lớp riêng của bạn mặc dù, vì vậy ... yeah.

>>> 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

Nâng cấp lên Python 3.1. Nó không sử dụng nhiều chữ số hơn mức cần thiết.

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

Đã sử dụng nó. Đó không phải là điểm, nhưng cảm ơn cho tip. – AkiRoss

-1

Nếu bạn đang sử dụng ngôn ngữ C, bạn có thể sử dụng #define hoặc "%*.*f" để làm điều đó, ví dụ

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

Anh ấy sử dụng thẻ python một cách rõ ràng, do đó anh ấy không sử dụng C – Bruce

2

Tôi đã gặp sự cố này ngày hôm nay và tôi đã đưa ra một giải pháp khác. Nếu bạn lo lắng về những gì nó trông giống như khi in, bạn có thể thay thế đối tượng tệp stdout bằng một tùy chỉnh, khi write() được gọi, tìm kiếm bất kỳ thứ gì trông giống như float, và thay thế chúng bằng định dạng của riêng bạn chúng.

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 

Sẽ không tốt nếu bạn chỉ đặt số vào một chuỗi, nhưng cuối cùng bạn có thể muốn viết chuỗi đó vào một số loại tệp ở đâu đó và bạn có thể bọc tệp đó đối tượng trên. Rõ ràng có một chút chi phí hiệu suất.

Cảnh báo công bằng: Tôi chưa thử nghiệm điều này trong Python 3, tôi không biết liệu nó có hoạt động hay không.

Các vấn đề liên quan