我有一份不平等名单。 我想从子列表中生成一个包含列表推导的新列表。
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'])]
任何想法如何让这个工作?
答案 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))