a1=[1,2,3,4,5,6]
b1=[[1,2,3], [4,5,6]]
如果使用np.shape
列表,a1
将返回(6,)
,而b1
将返回(2, 3)
。
如果禁止Numpy,如何获得列表a1
的形状?
我对如何让python程序知道a1
只是一个维度感到困惑。有什么好的方法吗?
答案 0 :(得分:1)
这是解决您的问题的递归尝试。只有在相同深度上的所有列表都具有相同的长度时,它才有效。否则会引发ValueError
:
from collections.abc import Sequence
def get_shape(lst, shape=()):
"""
returns the shape of nested lists similarly to numpy's shape.
:param lst: the nested list
:param shape: the shape up to the current recursion depth
:return: the shape including the current depth
(finally this will be the full depth)
"""
if not isinstance(lst, Sequence):
# base case
return shape
# peek ahead and assure all lists in the next depth
# have the same length
if isinstance(lst[0], Sequence):
l = len(lst[0])
if not all(len(item) == l for item in lst):
msg = 'not all lists have the same length'
raise ValueError(msg)
shape += (len(lst), )
# recurse
shape = get_shape(lst[0], shape)
return shape
给出您的输入(以及评论中的输入),结果如下:
a1=[1,2,3,4,5,6]
b1=[[1,2,3],[4,5,6]]
print(get_shape(a1)) # (6,)
print(get_shape(b1)) # (2, 3)
print(get_shape([[0,1], [2,3,4]])) # raises ValueError
print(get_shape([[[1,2],[3,4]],[[5,6],[7,8]]])) # (2, 2, 2)
不确定最后的结果是否是您想要的。
答案 1 :(得分:1)
这是Joel Grus的"Ten Essays on Fizz Buzz"书中使用递归的一个很好的例子。
with open('joblib_RL_Model.pkl', 'wb') as f:
pickle.dump(fitted_model, f)
with open('joblib_RL_Model.pkl', 'rb') as f:
joblib_LR_model = pickle.load(f)
示例:
from typing import List, Tuple, Union
def shape(ndarray: Union[List, float]) -> Tuple[int, ...]:
if isinstance(ndarray, list):
# More dimensions, so make a recursive call
outermost_size = len(ndarray)
row_shape = shape(ndarray[0])
return (outermost_size, *row_shape)
else:
# No more dimensions, so we're done
return ()
答案 2 :(得分:1)
问题明确指出“不使用 numpy”。但是,如果有人来到这里寻找没有任何条件的解决方案,请考虑以下。此解决方案适用于平衡列表。
b1=[[1,2,3], [4,5,6]]
np.asarray(b1).shape
(2, 3)
答案 3 :(得分:0)
>>>a = [1,2,3,4,5,6]
>>>print (len(a))
6
对于一维列表,可以使用上述方法。 len(list_name)返回列表中的元素数。
>>>a = [[1,2,3],[4,5,6]]
>>>nrow = len(a)
>>>ncol = len(a[0])
>>>nrow
2
>>>ncol
3
上面给出了列表的维度。 len(a)返回行数。 len(a [0])返回a [0]中的行数,即列数。
这里是原始答案的a link。
答案 4 :(得分:0)
根据所需的详尽程度,我建议使用尾递归。从最里面到最外面的列表建立形状。这样您就可以检查所有尺寸在每个深度和索引处是否匹配。
def shape(lst):
def ishape(lst):
shapes = [ishape(x) if isinstance(x, list) else [] for x in lst]
shape = shapes[0]
if shapes.count(shape) != len(shapes):
raise ValueError('Ragged list')
shape.append(len(lst))
return shape
return tuple(reversed(ishape(lst)))
这是IDEOne上的演示:https://ideone.com/HJRwlC
shapes.count(shape) != len(shapes)
是一个巧妙的技巧,它可以确定从给定https://stackoverflow.com/a/3844948/2988730中提取的所有形状是否都相同。
如果您唯一的目标是确定列表是否为一维,则只需在最外面的列表上运行一个all
:
is_1d = all(not isinstance(x, list) for x in lst)
OR
is_1d = not any(isinstance(x, list) for x in lst)
答案 5 :(得分:0)
Following 函数跟踪列表每个维度的第一项。它有多少维并不重要。
def list_shape(input):
shape = []
a = len(input)
shape.append(a)
b = input[0]
while a > 0:
try:
a = len(b)
shape.append(a)
b = b[0]
except:
break
return shape
list1 = [[[123], [231]], [[345], [231]]]
print(list_shape(list1))
输出:
[2, 2, 1]
注意:仅适用于对称列表和列表中的数字数据。