我有一个看起来像这样的列表:
data = ['1', '12', '123']
我想生成一个新列表,看起来像这样:
result = ['$1', '1', '$2', '12', '$3', '123']
其中
$
符号后面的数字是下一个元素的长度。
执行此操作的直接方法是使用
for
loop:
result = []
for element in data:
result += [f'${len(element)}'] + [element]
但我想知道是否可以以更优雅的方式来完成此操作 - 也许可以使用列表理解?
我可以做
result = [[f'${len(e)}', e] for e in data]
但是这个结果是一个列表列表:
[['$1', '1'], ['$2', '12'], ['$3', '123']]
我可以用
result = sum([[f'${len(e)}', e] for e in data], [])
甚至
result = [x for xs in [[f'${len(e)}', e] for e in data] for x in xs]
之类的东西来压平它,但这变得相当难以阅读。有一个更好的方法吗?
是的,可以使用列表推导式来实现,方法是在推导式内部使用
zip
函数:
data = ['1', '12', '123']
result = [x for pair in zip([f'${len(e)}' for e in data], data) for x in pair]
print(result) # 输出:['$1', '1', '$2', '12', '$3', '123']
这个方法是这样运作的:
-
创建长度对:
[f'${len(e)}' for e in data]
创建一个包含长度字符串的新列表(如'$1'
,'$2'
,'$3'
)。 -
使用
zip
函数配对:zip([f'${len(e)}' for e in data], data)
将长度字符串列表与其对应的元素配对在一起,生成一个迭代器,其中包含('$1', '1')
,('$2', '12')
,('$3', '123')
这样的元组。 -
使用嵌套循环展开元组:
外层的列表推导式
[x for pair in ... for x in pair]
迭代zip
函数返回的元组,并将每个元组pair
展开,从而创建一个包含所有元素的扁平列表。
这个方法比使用
sum
或嵌套列表推导式更简洁易懂,并且仍然利用了列表推导式的效率。