我正在使用 Python 2.7 并具有以下内容:
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
我想创建一个一维列表,其中元素按子列表中的位置排序,然后按子列表的顺序排序。所以上面列表的正确输出是:
[1, 4, 7, 2, 5, 8, 3, 6, 9]
这是我的(错误的)尝试:
def reorder_and_flatten(my_list):
my_list = [item for sublist in my_list for item in sublist]
result_nums = []
for i in range(len(my_list)):
result_nums.extend(my_list[i::3])
return result_nums
result = reorder_and_flatten(my_list)
这会展平我的二维列表并给出:
[1, 4, 7, 2, 5, 8, 3, 6, 9, 4, 7, 5, 8, 6, 9, 7, 8, 9]
此列表的前半部分是正确的,但后半部分不正确。
我还希望我的函数只能处理 2 个子列表。例如,如果给出:
[[1, 2, 3], [], [7, 8, 9]
正确的输出是:
[1, 7, 2, 8, 3, 9]
有什么想法吗?
谢谢!
请您参考如下方法:
您正在尝试展平,然后重新排序,这比重新排序然后展平要困难得多。
首先,对于您最初的问题,这只是“解压缩”,如 zip 的文档中所述。 :
>>> my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> list(zip(*my_list))
... [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
(在 Python 2.7 中,您可以在此处编写 zip(...) 而不是 list(zip(...)),但是这样,相同的演示将完全相同在 2.x 和 3.x 中)
然后,您已经知道如何将其展平:
>>> [item for sublist in zip(*my_list) for item in sublist]
[1, 4, 7, 2, 5, 8, 3, 6, 9]
但是对于第二种情况,事情变得有点复杂,其中一些列表可能是空的(或者可能更短?)。
没有类似于 zip 的函数,但会跳过缺失值。你可以很容易地写一个。但是相反……是一个类似于zip但用None(或您喜欢的任何其他东西)填充缺失值的函数,izip_longest .所以,我们可以只使用它,然后在展平时过滤掉 None 值:
>>> my_list = [[1, 2, 3], [], [7, 8, 9]]
>>> from itertools import izip_longest
>>> list(izip_longest(*my_list))
[(1, None, 7), (2, None, 8), (3, None, 9)]
>>> [item for sublist in izip_longest(*my_list) for item in sublist if item is not None]
[1, 7, 2, 8, 3, 9]
(在 Python 3 中,函数 izip_longest 被重命名为 zip_longest。)
值得注意的是 roundrobin 配方,如 ShadowRanger's answer 中所述, 是这个问题的更好解决方案,甚至更易于使用(只需从文档中复制并粘贴它,或者 pip install more_itertools 并从那里使用它)。它有点难理解——但值得花时间去理解它(如果遇到困难,请寻求帮助)。
