【问题标题】:return octuple patterns from nested sublists从嵌套子列表返回八元组模式
【发布时间】:2019-07-21 17:52:15
【问题描述】:

如何从 python 列表或从 numpy 数组更容易地创建下面描述的模式。

假设我有这样一个列表:

[
[a,a,0,a],
[0,b,0,b],
[c,0,c,c]
]

返回的列表应按遍历顺序循环嵌套列表(子列表 1 的元素 1,子列表 2 的元素 1,依此类推),但始终创建​​八元组列表大小。

[
 [a,0,c,0,0,0,0,0],
 [a,b,0,0,0,0,0,0],
 [0,0,c,0,0,0,0,0],
 [a,b,c,0,0,0,0,0]
]

在下一个示例中,我在子列表中有另一个子列表:

[
 [a,a,    0,   a],
 [0,[b,b],0,   b],
 [c,c    ,c,[c,c]]
]

生成的模式应该又是一次遍历。这里的规则是在子列表中处理这些列表中的元素之一相同,但是对于这些子列表中的元素二,只考虑具有这些深度的元素并将它们用在自己的八元组模式中。

[
 [a,0,c, 0,0,0,0,0],
 [a,b,c, 0,0,0,0,0],
 [0,b,0, 0,0,0,0,0],
 [0,0,c, 0,0,0,0,0],
 [a,b,c, 0,0,0,0,0],
 [0,0,c, 0,0,0,0,0],
]

另一个例子:

[
 [a    ,a     ] ,
 [b    ,[b,b,b]],
 [[c,c],0     ]
]

[
[a,b,c,0,0,0,0,0],
[0,0,c,0,0,0,0,0],
[a,b,0,0,0,0,0,0],
[0,b,0,0,0,0,0,0],
[0,b,0,0,0,0,0,0]
]

如果子列表的长度不同:

[
 [a,0],
 [b,[b,b],b]
]

[
 [a,b,0,0,0,0,0,0],
 [0,b,0,0,0,0,0,0],
 [0,b,0,0,0,0,0,0],
 [0,b,0,0,0,0,0,0]
]

有人可以告诉我一种如何处理遍历并使用嵌套列表处理这些异常并始终返回八元组的方法吗? 是否有其他容器或结构可以使这些模式更容易接收?

提前致谢

【问题讨论】:

  • 嵌套列表中有嵌套列表的次数是否有限制? [ [a, [ [ a, [ 0, 1 ] ], 5 ] ], [a, b]] 是可能的输入吗?
  • 当你的意思是一个子列表中可以有多少个子列表时,它是可变的。深度有一个最大值。所以在外部列表容器 [ ] 中保存所有子列表 [[sublist1], [sublist2],...],其中子列表可以包含简单值:..[a,a,a] 或例如[[c,c],[c,c,c]] 或混合。所以每个子列表要么没有深度,要么没有一级或混合 [b, [b,b,b,b,b,b], [b,b]]

标签: python python-3.x list


【解决方案1】:

以下是我解决问题的方法:

from functools import reduce

original = [
    ['a', 0],
    ['b', ['b', 'b'], 'b']
]

max_len = max([len(i) for i in original])
padded_original = [
    (i + [0] * max_len)[:max_len]
    for i in original
]
print(padded_original)
# [['a', 0, 0], ['b', ['b', 'b'], 'b']]

max_col_lens = reduce(
    lambda a, b: [max(a[i], b[i]) for i in range(len(a))],
    [
        [len(xi) if isinstance(xi, list) else 1 for xi in x]
        for x in padded_original
    ]
)
print(max_col_lens)
# [1, 2, 1]


original_transformed = [
    reduce(
        lambda a, b: a + b,
        [(item + [0] * size)[:size] for (item, size) in row]
    ) for row in [
        zip(
            [xi if isinstance(xi, list) else [xi] for xi in x],
            max_col_lens
        ) for x in padded_original
    ]
]
print(original_transformed)
# [['a', 0, 0, 0], ['b', 'b', 'b', 'b']]

result_list = [
    [0 for i in range(8)]
    for j in range(
        sum(
            reduce(
                lambda a, b: [max(a[i], b[i]) for i in range(len(a))],
                [
                    [len(xi) if isinstance(xi, list) else 1 for xi in x]
                    for x in padded_original
                ]
            )
        )
    )
]
print(result_list)
# [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]

# rotating transformed_original_transformed
for i in range(len(original_transformed)):
    for j in range(len(original_transformed[i])):
        result_list[j][i] = original_transformed[i][j]

print(result_list)
# [['a', 'b', 0, 0, 0, 0, 0, 0], [0, 'b', 0, 0, 0, 0, 0, 0], [0, 'b', 0, 0, 0, 0, 0, 0], [0, 'b', 0, 0, 0, 0, 0, 0]]

【讨论】:

  • 这不能回答 OP 的问题。这仅适用于第一个 use_case
  • 您好 Iprakashv,感谢您的代码。我仍然试图弄清楚它是如何工作的(列表推导仍然让我感到困惑)但现在我可以说它是有效的。非常感谢您的支持。完成测试后,我将标记为已完成。
  • 哦,我会在下一次编辑中尝试进一步简化它。稍后会发布。
猜你喜欢
  • 2018-08-16
  • 1970-01-01
  • 2013-03-04
  • 2023-04-03
  • 1970-01-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多