2011-08-16 13 views
9

Tôi có một chương trình liên quan đến cấu trúc dữ liệu lồng nhau trong đó loại cơ bản thường kết thúc bằng một số thập phân. ví dụ.Làm tròn số thập phân trong cấu trúc dữ liệu lồng nhau trong Python

x={'a':[1.05600000001,2.34581736481,[1.1111111112,9.999990111111]],...} 

Có cách nào đơn giản để in biến như vậy nhưng làm tròn tất cả các float để nói (3dp) và không giả định một cấu hình cụ thể của danh sách và từ điển? ví dụ.

{'a':[1.056,2.346,[1.111,10.000],...} 

Tôi đang nghĩ đến một cái gì đó giống như pformat(x,round=3) hoặc có thể

pformat(x,conversions={'float':lambda x: "%.3g" % x}) 

trừ tôi không nghĩ rằng họ có loại chức năng. Vĩnh viễn làm tròn các dữ liệu cơ bản là tất nhiên không phải là một lựa chọn.

+0

thế nào về việc chạy một vòng lặp như [sàn (x * 1000) /1000.0 cho x trong a]? –

+0

chỉ hoạt động đối với danh sách các số. – acrophobia

Trả lời

4

Điều này sẽ đệ quy xuống dicts, tuples, danh sách, vv định dạng số và để lại các công cụ khác một mình.

import collections 
import numbers 
def pformat(thing, formatfunc): 
    if isinstance(thing, dict): 
     return type(thing)((key, pformat(value)) for key, value in thing.iteritems()) 
    if isinstance(thing, collections.Container): 
     return type(thing)(pformat(value) for value in thing) 
    if isinstance(thing, numbers.Number): 
     return formatfunc(thing) 
    return thing 

def formatfloat(thing): 
    return "%.3g" % float(thing) 

x={'a':[1.05600000001,2.34581736481,[8.1111111112,9.999990111111]], 
'b':[3.05600000001,4.34581736481,[5.1111111112,6.999990111111]]} 

print pformat(x, formatfloat) 

Nếu bạn muốn thử và chuyển đổi tất cả mọi thứ vào một phao, bạn có thể làm

try: 
    return formatfunc(thing) 
except: 
    return thing 

thay vì ba dòng cuối cùng của hàm.

0
>>> b = [] 
>>> x={'a':[1.05600000001,2.34581736481,[1.1111111112,9.999990111111]]} 
>>> for i in x.get('a'): 
     if type(i) == type([]): 
      for y in i: 
       print("%0.3f"%(float(y))) 
     else: 
      print("%0.3f"%(float(i))) 


    1.056 
    2.346 
    1.111 
    10.000 

Vấn đề Ở đây chúng tôi không có phương pháp làm phẳng trong python, vì tôi biết nó chỉ là danh sách cấp 2 làm tổ tôi đã sử dụng for loop.

1

Một cách tiếp cận đơn giản giả sử bạn có danh sách nổi:

>>> round = lambda l: [float('%.3g' % e) if type(e) != list else round(e) for e in l] 
>>> print {k:round(v) for k,v in x.iteritems()} 
{'a': [1.06, 2.35, [1.11, 10.0]]} 
+0

Một lambda đề cập đến chính nó bằng tên chỉ là sai, đây là những gì được đặt tên chức năng hoặc y-combinator là cho :). Anh ấy cũng nói loại "thường kết thúc bằng số thập phân" vì vậy tôi nghĩ đôi khi chúng sẽ không thể "nổi". – agf

+0

Tôi sẽ để nó như một bài tập để người đọc trao đổi 'round = lambda l: ...' với 'def round (l): return ...': D – zeekay

+0

Nhưng y-combinator là tuyệt vời và có không bao giờ là lý do để sử dụng nó trong Python! – agf