Yih*_*uan 15 python python-3.x
a1=[1,2,3,4,5,6]
b1=[[1,2,3], [4,5,6]]
Run Code Online (Sandbox Code Playgroud)
如果使用np.shape
lista1
将返回(6,)
并且b1
将返回(2, 3)
.
如果禁止使用 Numpy,我如何获得 list 的形状a1
?
我主要对如何让python程序知道a1
只有一维感到困惑。有什么好的方法吗?
小智 21
>>>a = [1,2,3,4,5,6]
>>>print (len(a))
6
Run Code Online (Sandbox Code Playgroud)
对于一维列表,可以使用上述方法。len(list_name) 返回列表中的元素数。
>>>a = [[1,2,3],[4,5,6]]
>>>nrow = len(a)
>>>ncol = len(a[0])
>>>nrow
2
>>>ncol
3
Run Code Online (Sandbox Code Playgroud)
上面给出了列表的维度。len(a) 返回行数。len(a[0]) 返回 a[0] 中的行数,即列数。
这是原始答案的链接。
Reg*_*hew 11
该问题明确指出“不使用 numpy”。但是,如果有人到达这里寻找无条件的解决方案,请考虑以下内容。该解决方案适用于平衡列表。
b1=[[1,2,3], [4,5,6]]
np.asarray(b1).shape
Run Code Online (Sandbox Code Playgroud)
(2, 3)
这是解决您的问题的递归尝试。只有在相同深度的所有列表都具有相同的长度时,它才会起作用。否则它会引发一个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
Run Code Online (Sandbox Code Playgroud)
鉴于您的输入(以及来自评论的输入),这些是结果:
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)
Run Code Online (Sandbox Code Playgroud)
不确定最后的结果是否是您想要的。
更新
正如mkl在评论中指出的那样,上面的代码不会捕获嵌套列表形状不一致的所有情况;例如[[0, 1], [2, [3, 4]]]
不会引发错误。
这是检查形状是否一致的一个镜头(可能有更有效的方法来做到这一点......)
from collections.abc import Sequence, Iterator
from itertools import tee, chain
def is_shape_consistent(lst: Iterator):
"""
check if all the elements of a nested list have the same
shape.
first check the 'top level' of the given lst, then flatten
it by one level and recursively check that.
:param lst:
:return:
"""
lst0, lst1 = tee(lst, 2)
try:
item0 = next(lst0)
except StopIteration:
return True
is_seq = isinstance(item0, Sequence)
if not all(is_seq == isinstance(item, Sequence) for item in lst0):
return False
if not is_seq:
return True
return is_shape_consistent(chain(*lst1))
Run Code Online (Sandbox Code Playgroud)
可以这样使用:
lst0 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
lst1 = [[0, 1, 2], [3, [4, 5]], [7, [8, 9]]]
assert is_shape_consistent(iter(lst0))
assert not is_shape_consistent(iter(lst1))
Run Code Online (Sandbox Code Playgroud)