如何使用不相等的子列表在python中创建列表解析

时间:2018-03-08 15:38:29

标签: python

我有一份不平等名单。 我想从子列表中生成一个包含列表推导的新列表。

s = [['a','b','c','d'],['e','f','g'],['h','i'],['j','k','l','m']]

我正在尝试以下代码,但它不断引发indexError:

new_s = []
for i in range(len(s)):
    new_s.append((i,[t[i] for t in s if t[i]))

预期输出为:

new_s = [(0,['a','e','h','j']),(1,['b','f','i','k']),(2,['c','g','l']),(3,['d','m'])]

任何想法如何让这个工作?

3 个答案:

答案 0 :(得分:12)

您可以使用itertools.zip_longest以元素方式迭代每个子列表,同时使用None作为较短子列表的填充值。

然后使用filter删除填充中使用的None值。

所有这一切都在列表理解中:

>>> from itertools import zip_longest
>>> [(i, list(filter(None, j))) for i, j in enumerate(zip_longest(*s))]
[(0, ['a', 'e', 'h', 'j']), (1, ['b', 'f', 'i', 'k']), (2, ['c', 'g', 'l']), (3, ['d', 'm'])]

答案 1 :(得分:0)

一个没有itertools但修改原始列表。

def until_depleted():
   while any(sl for sl in s):
    yield 1

list(enumerate(list(s_l.pop(0) for s_l in s if s_l) for _ in until_depleted()))

一个没有修改原件而是带有计数器

idx = 0
max_idx = max(len(_) for _ in s)

def until_maxidx():
    global idx
    while idx < max_idx:
        yield 1
        idx += 1

list(enumerate(list(s_l[idx] for s_l in s if idx < len(s_l)) for _ in until_maxidx()))

更明确的一个没有内在理解也没有调用生成器:

ret = []
idx = 0
max_idx = max(len(_) for _ in s)
while idx < max_idx:
    ret.append(list(s_l[idx] for s_l in s if idx < len(s_l)))
    idx += 1

print(list(enumerate(ret)))

答案 2 :(得分:0)

这没有itertools,但也没有理解,所以我不知道它是否算作解决方案。

s = [['a','b','c','d'],['e','f','g'],['h','i'],'j','k','l','m']]

new_s = []
for i in range(len(s)):
    tmp = []
    for item in s:
        tmp.extend(item[i:i+1])
    new_s.append((i, tmp))