我目前正在将一些 Python 翻译成 F#,具体来说神经网络和深度学习.
为了确保数据结构正确转换,需要 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"|])
返回与值无关的签名
整型[][]*字符串[]
* is a tuple item separator
int [] [] is a two dimensional jagged array of int
string [] is a one dimensional array of string
这可以或者如何在 Python 中完成?
TLDR;
目前,我将 PyCharm 与调试器一起使用,并在变量窗口中单击单个变量的视图选项以查看详细信息。问题是输出包含混合的值和类型,而我只需要类型签名。当变量类似于 (float[50000][784], int[50000]) 时,这些值就会产生妨碍。是的,我现在正在调整变量的大小,但这是一种解决方法,而不是解决方案。
e.g.
Using PyCharm 社区
(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]))
Using Spyder
![Using Spyder variable viewer](https://i.stack.imgur.com/XTivP.png)
Using Visual Studio 社区 with Visual Studio 的 Python 工具
(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))
EDIT:
由于这个问题已经被关注,显然有人正在寻找更多细节,这是我的修改版本,它也可以处理numpy ndarray。谢谢Vlad对于初始版本。
还因为使用了变体游程长度编码还有没有更多的用处?对于异构类型。
# 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
我不认为它已经完成,但到目前为止它已经满足了我需要的一切。