如何删除不同长度列表列表中的最内层嵌套
How to remove the innermost level of nesting in a list of lists of varying lengths
我正在尝试删除单元素长度列表列表中的最内层嵌套。你知道一个相对简单的方法(转换为 NumPy 数组很好)从:
[[[1], [2], [3], [4], [5]], [[6], [7], [8]], [[11], [12]]]
到这个?:
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
此外,我尝试执行此操作的真实列表包含日期时间对象,而不是示例中的整数。列表的初始集合将具有不同的长度。
或者,如果原始列表中有 nans 就好了,这样只要输出列表中不存在 nans,每个列表的长度就相同。即
[[[1], [2], [3], [4], [5]],
[[6], [7], [8], [nan], [nan]],
[[11], [12], [nan], [nan], [nan]]]
对此:
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
试试这个:
l = [ [ [1],[2],[3],[4],[5] ],
[ [6],[7],[8], [None],[None]] ,
[ [11],[12],[None],[None],[None]] ]
l = [ [x[0] for x in s if x[0] is not None] for s in l]
>>> from operator import add
>>> lists = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
>>> [reduce(add, lst) for lst in lists]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
这不是一个非常有效的方法,因为它会在每次调用 add 时重建一个列表。
或者,您可以使用 sum
或简单的列表理解,如其他答案所示。
如果嵌套总是一致的,那么这是微不足道的:
In [2]: import itertools
In [3]: nested = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
In [4]: unested = [list(itertools.chain(*sub)) for sub in nested]
In [5]: unested
Out[5]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
请注意,利用列表的 add
的解决方案将为您提供 O(n^2) 性能,其中 n 是每个子列表中合并的子列表的数量。
np.squeeze
怎么样?
Remove single-dimensional entries from the shape of an array.
arr = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
>>> arr
[[[1], [2], [3], [4], [5]], [[6], [7], [8]], [[11], [12]]]
>>> [np.squeeze(i) for i in arr]
[array([1, 2, 3, 4, 5]), array([6, 7, 8]), array([11, 12])]
但不一定是最内层(即独立于多少维度)的维度。但是你的问题指定 "list of lists"
与您的情况一样,最里面的对象只有一个元素。您可以访问基于 index 的值,而不是使用一些附加函数。例如:
>>> [[y[0] for y in x] for x in my_list]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果您的最内层列表可能有多个元素,您可以这样做:
>>> [[z for y in x for z in y] for x in my_list]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果您知道嵌套级别,那么其中一种列表理解就很容易了。
In [129]: ll=[ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
In [130]: [[j[0] for j in i] for i in ll] # simplest
Out[130]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果标准只是去掉一个内层的嵌套,不管嵌套有多深,代码都需要多加思考。我可能会尝试将其编写为递归函数。
np.nan
(或None
)填充对列表版本没有帮助
In [131]: lln=[ [ [1],[2],[3],[4],[5] ], [ [6],[7],[8],[nan],[nan]] , [ [11],[12],[nan],[nan],[nan] ] ]
In [132]: [[j[0] for j in i if j[0] is not np.nan] for i in lln]
Out[132]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
填充确实让我们制作了一个 3d 数组,然后可以轻松地对其进行压缩:
In [135]: arr = np.array(lln)
In [136]: arr.shape
Out[136]: (3, 5, 1)
In [137]: arr = arr[:,:,0]
In [138]: arr
Out[138]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., nan, nan],
[ 11., 12., nan, nan, nan]])
但是接下来的问题是如何删除那些 nan
并创建参差不齐的子列表。
掩码数组可以让您使用二维数组而不会被这些nan
:
打扰
In [141]: M = np.ma.masked_invalid(arr)
In [142]: M
Out[142]:
masked_array(data =
[[1.0 2.0 3.0 4.0 5.0]
[6.0 7.0 8.0 -- --]
[11.0 12.0 -- -- --]],
mask =
[[False False False False False]
[False False False True True]
[False False True True True]],
fill_value = 1e+20)
In [144]: M.sum(axis=1) # e.g. sublist sums
Out[144]:
masked_array(data = [15.0 21.0 23.0],
mask = [False False False],
fill_value = 1e+20)
从 arr
中删除 nan
可能是列表理解最简单的方法。值是浮点数,因为 np.nan
是浮点数。
In [153]: [[i for i in row if ~np.isnan(i)] for row in arr]
Out[153]: [[1.0, 2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0], [11.0, 12.0]]
所以填充没有帮助。
如果使用 None
进行填充,则数组将是对象 dtype,更接近字符嵌套列表。
In [163]: lln
Out[163]:
[[[1], [2], [3], [4], [5]],
[[6], [7], [8], [None], [None]],
[[11], [12], [None], [None], [None]]]
In [164]: arr=np.array(lln)[:,:,0]
In [165]: arr
Out[165]:
array([[1, 2, 3, 4, 5],
[6, 7, 8, None, None],
[11, 12, None, None, None]], dtype=object)
In [166]: [[i for i in row if i is not None] for row in arr]
Out[166]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
另一种数组方法是在第2层计算有效元素的数量;压平整个东西,然后 split
.
一个递归函数:
def foo(alist):
if len(alist)==1:
return alist[0]
else:
return [foo(i) for i in alist if foo(i) is not None]
In [200]: ll=[ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [11], [[[12],[13]]]]
In [201]: foo(ll)
Out[201]: [[1, 2, 3, 4, 5], [6, 7, 8], 11, [[12], [13]]]
In [202]: lln=[ [ [1],[2],[3],[4],[5] ], [ [6],[7],[8],[None],[None]] , [ [11],[12],[None],[None],[None] ] ]
In [203]: foo(lln)
Out[203]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
它向下递归到列表长度为 1 的层级。它仍然很脆弱,并且如果嵌套层级不同就会出现问题。从概念上讲,它与 @piRSquared's
答案非常相似。
因为这个问题看起来很有趣!
我使用了一个递归函数来解压只有一个值的列表。
def make_singular(l):
try:
if len(l) == 1:
return l[0]
else:
return [make_singular(l_) for l_ in l]
except:
return l
nest = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
make_singular(nest)
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
我正在尝试删除单元素长度列表列表中的最内层嵌套。你知道一个相对简单的方法(转换为 NumPy 数组很好)从:
[[[1], [2], [3], [4], [5]], [[6], [7], [8]], [[11], [12]]]
到这个?:
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
此外,我尝试执行此操作的真实列表包含日期时间对象,而不是示例中的整数。列表的初始集合将具有不同的长度。
或者,如果原始列表中有 nans 就好了,这样只要输出列表中不存在 nans,每个列表的长度就相同。即
[[[1], [2], [3], [4], [5]],
[[6], [7], [8], [nan], [nan]],
[[11], [12], [nan], [nan], [nan]]]
对此:
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
试试这个:
l = [ [ [1],[2],[3],[4],[5] ],
[ [6],[7],[8], [None],[None]] ,
[ [11],[12],[None],[None],[None]] ]
l = [ [x[0] for x in s if x[0] is not None] for s in l]
>>> from operator import add
>>> lists = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
>>> [reduce(add, lst) for lst in lists]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
这不是一个非常有效的方法,因为它会在每次调用 add 时重建一个列表。
或者,您可以使用 sum
或简单的列表理解,如其他答案所示。
如果嵌套总是一致的,那么这是微不足道的:
In [2]: import itertools
In [3]: nested = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
In [4]: unested = [list(itertools.chain(*sub)) for sub in nested]
In [5]: unested
Out[5]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
请注意,利用列表的 add
的解决方案将为您提供 O(n^2) 性能,其中 n 是每个子列表中合并的子列表的数量。
np.squeeze
怎么样?
Remove single-dimensional entries from the shape of an array.
arr = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
>>> arr
[[[1], [2], [3], [4], [5]], [[6], [7], [8]], [[11], [12]]]
>>> [np.squeeze(i) for i in arr]
[array([1, 2, 3, 4, 5]), array([6, 7, 8]), array([11, 12])]
但不一定是最内层(即独立于多少维度)的维度。但是你的问题指定 "list of lists"
与您的情况一样,最里面的对象只有一个元素。您可以访问基于 index 的值,而不是使用一些附加函数。例如:
>>> [[y[0] for y in x] for x in my_list]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果您的最内层列表可能有多个元素,您可以这样做:
>>> [[z for y in x for z in y] for x in my_list]
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果您知道嵌套级别,那么其中一种列表理解就很容易了。
In [129]: ll=[ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
In [130]: [[j[0] for j in i] for i in ll] # simplest
Out[130]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
如果标准只是去掉一个内层的嵌套,不管嵌套有多深,代码都需要多加思考。我可能会尝试将其编写为递归函数。
np.nan
(或None
)填充对列表版本没有帮助
In [131]: lln=[ [ [1],[2],[3],[4],[5] ], [ [6],[7],[8],[nan],[nan]] , [ [11],[12],[nan],[nan],[nan] ] ]
In [132]: [[j[0] for j in i if j[0] is not np.nan] for i in lln]
Out[132]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
填充确实让我们制作了一个 3d 数组,然后可以轻松地对其进行压缩:
In [135]: arr = np.array(lln)
In [136]: arr.shape
Out[136]: (3, 5, 1)
In [137]: arr = arr[:,:,0]
In [138]: arr
Out[138]:
array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., nan, nan],
[ 11., 12., nan, nan, nan]])
但是接下来的问题是如何删除那些 nan
并创建参差不齐的子列表。
掩码数组可以让您使用二维数组而不会被这些nan
:
In [141]: M = np.ma.masked_invalid(arr)
In [142]: M
Out[142]:
masked_array(data =
[[1.0 2.0 3.0 4.0 5.0]
[6.0 7.0 8.0 -- --]
[11.0 12.0 -- -- --]],
mask =
[[False False False False False]
[False False False True True]
[False False True True True]],
fill_value = 1e+20)
In [144]: M.sum(axis=1) # e.g. sublist sums
Out[144]:
masked_array(data = [15.0 21.0 23.0],
mask = [False False False],
fill_value = 1e+20)
从 arr
中删除 nan
可能是列表理解最简单的方法。值是浮点数,因为 np.nan
是浮点数。
In [153]: [[i for i in row if ~np.isnan(i)] for row in arr]
Out[153]: [[1.0, 2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0], [11.0, 12.0]]
所以填充没有帮助。
如果使用 None
进行填充,则数组将是对象 dtype,更接近字符嵌套列表。
In [163]: lln
Out[163]:
[[[1], [2], [3], [4], [5]],
[[6], [7], [8], [None], [None]],
[[11], [12], [None], [None], [None]]]
In [164]: arr=np.array(lln)[:,:,0]
In [165]: arr
Out[165]:
array([[1, 2, 3, 4, 5],
[6, 7, 8, None, None],
[11, 12, None, None, None]], dtype=object)
In [166]: [[i for i in row if i is not None] for row in arr]
Out[166]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
另一种数组方法是在第2层计算有效元素的数量;压平整个东西,然后 split
.
一个递归函数:
def foo(alist):
if len(alist)==1:
return alist[0]
else:
return [foo(i) for i in alist if foo(i) is not None]
In [200]: ll=[ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [11], [[[12],[13]]]]
In [201]: foo(ll)
Out[201]: [[1, 2, 3, 4, 5], [6, 7, 8], 11, [[12], [13]]]
In [202]: lln=[ [ [1],[2],[3],[4],[5] ], [ [6],[7],[8],[None],[None]] , [ [11],[12],[None],[None],[None] ] ]
In [203]: foo(lln)
Out[203]: [[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]
它向下递归到列表长度为 1 的层级。它仍然很脆弱,并且如果嵌套层级不同就会出现问题。从概念上讲,它与 @piRSquared's
答案非常相似。
因为这个问题看起来很有趣!
我使用了一个递归函数来解压只有一个值的列表。
def make_singular(l):
try:
if len(l) == 1:
return l[0]
else:
return [make_singular(l_) for l_ in l]
except:
return l
nest = [ [ [1],[2],[3],[4], [5] ], [ [6],[7],[8] ] , [ [11],[12] ] ]
make_singular(nest)
[[1, 2, 3, 4, 5], [6, 7, 8], [11, 12]]