我目前正在將一些Python翻譯成F#,特別是neural-networks-and-deep-learning。如何確定Python中嵌套數據結構的類型?
爲了確保數據結構正確轉換,需要Python中嵌套類型的詳細信息。 type()函數適用於簡單類型,但不適用於嵌套類型。
例如在Python:
> data = ([[1,2,3],[4,5,6],[7,8,9]],["a","b","c"])
> type(data)
<type 'tuple'>
只給出了第一級的類型。對元組中的數組沒有任何瞭解。
我希望這樣的事情是什麼F#不
> let data = ([|[|1;2;3|];[|4;5;6|];[|7;8;9|]|],[|"a";"b";"c"|]);;
val data : int [] [] * string [] =
([|[|1; 2; 3|]; [|4; 5; 6|]; [|7; 8; 9|]|], [|"a"; "b"; "c"|])
返回簽名獨立的價值
INT [] [] *字符串[]
* is a tuple item separator int [] [] is a two dimensional jagged array of int string [] is a one dimensional array of string
Python或Python可以做到這一點嗎?
TLDR;
目前我正在使用PyCharm與調試器,並在變量窗口中單擊單個變量的查看選項以查看詳細信息。問題是輸出包含值以及混合類型,我只需要類型簽名。當變量類似於(float [50000] [784],int [50000])時,這些值會成爲問題。是的,我現在正在調整變量的大小,但這是一種解決方法,而不是解決方案。
例如
(array([[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32),
array([7, 2, 1, ..., 4, 5, 6]))
使用Spyder
使用Visual Studio Community與Python Tools for Visual Studio
(array([[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32),
array([5, 0, 4, ..., 8, 4, 8], dtype=int64))
編輯:
由於這個問題已被盯着某人顯然是尋找更多的細節,這裏是我的修改後的版本,它也可以處理numpy ndarray。感謝Vlad的初始版本。
也因爲使用Run Length Encoding的變化,沒有更多的使用?針對異構類型。
# Note: Typing for elements of iterable types such as Set, List, or Dict
# use a variation of Run Length Encoding.
def type_spec_iterable(iterable, name):
def iterable_info(iterable):
# With an iterable for it to be comparable
# the identity must contain the name and length
# and for the elements the type, order and count.
length = 0
types_list = []
pervious_identity_type = None
pervious_identity_type_count = 0
first_item_done = False
for e in iterable:
item_type = type_spec(e)
if (item_type != pervious_identity_type):
if not first_item_done:
first_item_done = True
else:
types_list.append((pervious_identity_type, pervious_identity_type_count))
pervious_identity_type = item_type
pervious_identity_type_count = 1
else:
pervious_identity_type_count += 1
length += 1
types_list.append((pervious_identity_type, pervious_identity_type_count))
return (length, types_list)
(length, identity_list) = iterable_info(iterable)
element_types = ""
for (identity_item_type, identity_item_count) in identity_list:
if element_types == "":
pass
else:
element_types += ","
element_types += identity_item_type
if (identity_item_count != length) and (identity_item_count != 1):
element_types += "[" + `identity_item_count` + "]"
result = name + "[" + `length` + "]<" + element_types + ">"
return result
def type_spec_dict(dict, name):
def dict_info(dict):
# With a dict for it to be comparable
# the identity must contain the name and length
# and for the key and value combinations the type, order and count.
length = 0
types_list = []
pervious_identity_type = None
pervious_identity_type_count = 0
first_item_done = False
for (k, v) in dict.iteritems():
key_type = type_spec(k)
value_type = type_spec(v)
item_type = (key_type, value_type)
if (item_type != pervious_identity_type):
if not first_item_done:
first_item_done = True
else:
types_list.append((pervious_identity_type, pervious_identity_type_count))
pervious_identity_type = item_type
pervious_identity_type_count = 1
else:
pervious_identity_type_count += 1
length += 1
types_list.append((pervious_identity_type, pervious_identity_type_count))
return (length, types_list)
(length, identity_list) = dict_info(dict)
element_types = ""
for ((identity_key_type,identity_value_type), identity_item_count) in identity_list:
if element_types == "":
pass
else:
element_types += ","
identity_item_type = "(" + identity_key_type + "," + identity_value_type + ")"
element_types += identity_item_type
if (identity_item_count != length) and (identity_item_count != 1):
element_types += "[" + `identity_item_count` + "]"
result = name + "[" + `length` + "]<" + element_types + ">"
return result
def type_spec_tuple(tuple, name):
return name + "<" + ", ".join(type_spec(e) for e in tuple) + ">"
def type_spec(obj):
object_type = type(obj)
name = object_type.__name__
if (object_type is int) or (object_type is long) or (object_type is str) or (object_type is bool) or (object_type is float):
result = name
elif object_type is type(None):
result = "(none)"
elif (object_type is list) or (object_type is set):
result = type_spec_iterable(obj, name)
elif (object_type is dict):
result = type_spec_dict(obj, name)
elif (object_type is tuple):
result = type_spec_tuple(obj, name)
else:
if name == 'ndarray':
ndarray = obj
ndarray_shape = "[" + `ndarray.shape`.replace("L","").replace(" ","").replace("(","").replace(")","") + "]"
ndarray_data_type = `ndarray.dtype`.split("'")[1]
result = name + ndarray_shape + "<" + ndarray_data_type + ">"
else:
result = "Unknown type: " , name
return result
我不認爲它完成了,但它已經在我到目前爲止所需的一切工作。
你可能能夠爲自己的元組一起破解自己的東西,但不能用於列表或字典,因爲它們是無類型的(元組也是,但至少它們是不可變的)。什麼應該是'[1,2,'c']'的類型? – L3viathan
數據來自可預測的結構性來源嗎?或者它真的只是偶然? – Monkpit
您是試圖從正在運行的腳本中的變量推導出這些類型,還是從代碼本身推導出它們?生成一個列表或元組是一回事,然後通過它遍歷每個級別的類型。查看代碼並且推導它產生的內容(不運行它)是另一回事。 – hpaulj