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

时间:2018-08-22 06:21:11

标签: python python-3.x

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只是一个维度感到困惑。有什么好的方法吗?

6 个答案:

答案 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]

注意:仅适用于对称列表和列表中的数字数据。