为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不使用 numpy 的情况下获得列表形状?

如何在不使用 numpy 的情况下获得列表形状?

犯罪嫌疑人X 2021-05-30 06:15:07
a1=[1,2,3,4,5,6]  b1=[[1,2,3], [4,5,6]]如果使用np.shapelista1将返回(6,)并且b1将返回(2, 3).如果禁止使用 Numpy,我如何获得 list 的形状a1?我主要对如何让python程序知道a1只有一维感到困惑。有什么好的方法吗?
查看完整描述

3 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

>>>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]中的行数,即列数。


查看完整回答
反对 回复 2021-06-01
?
喵喔喔

TA贡献1735条经验 获得超5个赞

这是解决您的问题的递归尝试。只有在相同深度的所有列表都具有相同的长度时,它才会起作用。否则会引发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)

不知道最后的结果是否是您想要的。


更新


正如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))

可以这样使用:


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))


查看完整回答
反对 回复 2021-06-01
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

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)


查看完整回答
反对 回复 2021-06-01
  • 3 回答
  • 0 关注
  • 398 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号