Python 如何在不使用 numpy 的情况下获得列表形状?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51960857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get a list shape without using numpy?
提问by Yihong Guan
a1=[1,2,3,4,5,6]
b1=[[1,2,3], [4,5,6]]
If using np.shape
list a1
will return (6,)
and b1
will return (2, 3)
.
如果使用np.shape
lista1
将返回(6,)
并且b1
将返回(2, 3)
.
If Numpy is forbidden, how can I get the shape of list a1
?
如果禁止使用 Numpy,我如何获得 list 的形状a1
?
I am mainly confused about how can I let the python program know a1
is only one dimension. Is there any good method?
我主要对如何让python程序知道a1
只有一维感到困惑。有什么好的方法吗?
回答by Arun
>>>a = [1,2,3,4,5,6]
>>>print (len(a))
6
For one dimensional lists, the above method can be used. len(list_name) returns number of elements in the list.
对于一维列表,可以使用上述方法。len(list_name) 返回列表中的元素数。
>>>a = [[1,2,3],[4,5,6]]
>>>nrow = len(a)
>>>ncol = len(a[0])
>>>nrow
2
>>>ncol
3
The above gives the dimension of the list. len(a) returns number of rows. len(a[0]) returns number of rows in a[0] which is the number of columns.
上面给出了列表的维度。len(a) 返回行数。len(a[0]) 返回 a[0] 中的行数,即列数。
Here's a linkto original answer.
这是原始答案的链接。
回答by hiro protagonist
this is a recursive attempt at solving your problem. it will only work if all the lists on the same depth have the same length. otherwise it will raise a ValueError
:
这是解决您的问题的递归尝试。只有在相同深度的所有列表都具有相同的长度时,它才会起作用。否则它会引发一个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
given your input (and the inputs from the comments) these are the results:
鉴于您的输入(以及来自评论的输入),这些是结果:
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)
not sure if the last result is what you wanted.
不确定最后的结果是否是您想要的。
回答by Mad Physicist
Depending on the level of thoroughness required, I would recommend using tail recursion. Build up the shape from the innermost to the outermost list. That will allow you to check that all the sizes match up at every depth and index.
根据所需的彻底程度,我建议使用尾递归。从最里面到最外面的列表构建形状。这将允许您检查所有尺寸是否在每个深度和索引处匹配。
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)))
Here is a demo on IDEOne: https://ideone.com/HJRwlC
这是 IDEOne 上的演示:https://ideone.com/HJRwlC
shapes.count(shape) != len(shapes)
is a neat trick to determine if all the shapes up to a given level are identical, taken from https://stackoverflow.com/a/3844948/2988730.
shapes.count(shape) != len(shapes)
是一个巧妙的技巧,用于确定达到给定级别的所有形状是否相同,取自https://stackoverflow.com/a/3844948/2988730。
If your only goal is to determine whether the list is one dimensional or not, just run a single all
on the outermost list:
如果您的唯一目标是确定列表是否是一维的,只需all
在最外面的列表上运行一个:
is_1d = all(not isinstance(x, list) for x in lst)
OR
或者
is_1d = not any(isinstance(x, list) for x in lst)