Python 如何在不使用numpy的情况下获得列表形状?
如果使用Python 如何在不使用numpy的情况下获得列表形状?,python,python-3.x,Python,Python 3.x,如果使用np.shape列表a1将返回(6,),b1将返回(2,3) 如果Numpy被禁止,我如何获得lista1的形状 我主要困惑于如何让python程序知道a1只是一个维度。有什么好方法吗?这是解决问题的递归尝试。只有当同一深度上的所有列表长度相同时,它才会起作用。否则将引发值错误: a1=[1,2,3,4,5,6] b1=[[1,2,3], [4,5,6]] 根据您的输入(以及评论中的输入),结果如下: from collections.abc import Sequence d
np.shape
列表a1
将返回(6,)
,b1
将返回(2,3)
如果Numpy被禁止,我如何获得lista1
的形状
我主要困惑于如何让python程序知道
a1
只是一个维度。有什么好方法吗?这是解决问题的递归尝试。只有当同一深度上的所有列表长度相同时,它才会起作用。否则将引发值错误:
a1=[1,2,3,4,5,6]
b1=[[1,2,3], [4,5,6]]
根据您的输入(以及评论中的输入),结果如下:
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
不确定最后的结果是否是你想要的
更新
正如上面代码在注释中指出的那样,嵌套列表的形状不一致的情况不会全部出现;e、 g.[[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))
对于一维列表,可以使用上述方法。len(list_name)返回列表中的元素数
>>>a = [1,2,3,4,5,6]
>>>print (len(a))
6
上面给出了列表的维度。len(a)返回行数。len(a[0])返回[0]中的行数,即列数
以下是原始答案。根据所需的彻底程度,我建议使用尾部递归。从最内层到最外层列表构建形状。这将允许您检查每个深度和索引的所有大小是否匹配
>>>a = [[1,2,3],[4,5,6]]
>>>nrow = len(a)
>>>ncol = len(a[0])
>>>nrow
2
>>>ncol
3
以下是关于IDEOne的演示:
shape.count(shape)!=len(shapes)
是一个巧妙的技巧,用于确定给定级别的所有形状是否相同
如果您的唯一目标是确定列表是否为一维,只需在最外层的列表上运行一个all
:
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)))
或
这是JoelGrus的书中使用递归的一个很好的例子
is_1d = not any(isinstance(x, list) for x in lst)
例如:
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 ()
下面的函数跟踪列表中每个维度的第一项。不管它有多少维度
three_d = [
[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
[[0, 0, 0], [1, 1, 1], [2, 2, 2]],
]
result = shape(three_d)
print(result)
>>> (5, 3, 3)
输出:
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))
注:仅适用于对称列表和列表中的数字数据。问题明确说明“不使用numpy”。然而,如果有人到达这里寻找一个没有任何条件的解决方案,请考虑下面。此解决方案适用于平衡列表
>>>a = [1,2,3,4,5,6]
>>>print (len(a))
6
[2, 2, 1]
(2,3)列表
对象没有尺寸或形状。它们只有一个长度。无论如何,如果x=[[1,2,3],[4,5]]
形状应该是什么?如果列表中的每个列表都有相同数量的元素,那么“形状”应该是(len(b1),len(b1[0])
@grshankar关于:[[1,2],[3,4],[5,6],[7,8]
?在任何情况下,OP都没有充分说明问题所在。您面临的实际问题是什么?为什么必须“让python程序知道a1
只是一维的”?请注意,检查if not all(len(item)==l表示lst中的item):raise
不会捕获所有不一致。例如,get_shape([[0,1],[2[3,4]])
返回(2,2)
,但是[[0,1],[2[3,4]]]
没有定义良好的形状。@mkl-oh。这是一个很好的观点…@mkl您可以额外计算嵌套列表中的元素总数,并检查它是否与形状中条目的乘积相匹配…如果您使用[[0]]
,它具有形状(1,1)
,则您只需计算“死胡同”,即非列表元素。但是你的条件在[[0,1,2],[3,4,5],[7,8,9]]
上失败了,它有9个元素,“shape”(3,3)
@mkl添加了一个函数,该函数应该能够验证这些形状是否一致。没有经过很好的测试。。。它还能被愚弄吗?你有没有更有效的方法?
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]
b1=[[1,2,3], [4,5,6]]
np.asarray(b1).shape