Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在不使用numpy的情况下获得列表形状?_Python_Python 3.x - Fatal编程技术网

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被禁止,我如何获得list
a1
的形状


我主要困惑于如何让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