给出此嵌套列表:
foo = [["apple", "cherry"], ["banana"], ["pear", "raspberry", "pineapple"]]
我想保留结构并将所有项目替换为连续的数字。我想要的输出是:
[[0, 1], [2], [3, 4, 5]]
我希望有一个简单的单线飞机,但是我想到的最短的可行解决方案是:
foo_numbers = []
count = 0
for i, sublist in enumerate(foo):
foo_numbers.append([])
for item in sublist:
foo_numbers[i].append(count)
count += 1
通常,这些手动迭代器表明,有更多的Python方式可以实现相同的目的。如果要使用列表解析来完成此操作,我将看不到如何为两个循环组成一个“共享计数器”,因此它不会从每个sublist
的零开始。
答案 0 :(得分:5)
您可以将itertools.count
与嵌套列表理解结合使用:
from itertools import count
foo = [["apple", "cherry"], ["banana"], ["pear", "raspberry", "pineapple"]]
c = count() # 0 start is default, e.g. count(1) will start from 1
res = [[next(c) for _ in lst] for lst in foo]
print(res)
# [[0, 1], [2], [3, 4, 5]]
答案 1 :(得分:2)
比较这些解决方案:
import itertools
def f1(foo):
"""original version in question"""
foo_numbers = []
count = 0
for i, sublist in enumerate(foo):
foo_numbers.append([])
for item in sublist:
foo_numbers[i].append(count)
count += 1
return foo_numbers
def f2(foo):
"""@jpp answer"""
c = itertools.count()
return [[next(c) for _ in range(len(lst))] for lst in foo]
def f3(foo):
"""@DanielMesejo answer"""
foo_numbers = []
count = 0
for i, sublist in enumerate(foo):
foo_numbers.append([j for j in range(count, len(sublist) + count)])
count += len(sublist)
return foo_numbers
给我们这个:
>>> import timeit
>>>
>>> timeit.timeit('f(foo)', 'from __main__ import f1 as f, foo')
1.2990377170499414
>>> timeit.timeit('f(foo)', 'from __main__ import f2 as f, foo')
2.260929798008874
>>> timeit.timeit('f(foo)', 'from __main__ import f3 as f, foo')
2.1552230638917536
似乎原始版本的速度更快(提高了2倍)。
答案 2 :(得分:2)
您可以使用list comprehension代替内部循环:
foo = [["apple", "cherry"], ["banana"], ["pear", "raspberry", "pineapple"]]
foo_numbers = []
count = 0
for i, sublist in enumerate(foo):
foo_numbers.append([j for j in range(count, len(sublist) + count)])
count += len(sublist)
print(foo_numbers)
输出
[[0, 1], [2], [3, 4, 5]]
通常,列表理解比列表创建循环要快。或者,您可以将范围对象转换为列表,如下所示:
foo_numbers.append(list(range(count, len(sublist) + count)))
答案 3 :(得分:0)
如果您确实do not要导入任何内容,请使用以下给定的解决方案:
foo = [["apple", "cherry"], ["banana"], ["pear", "raspberry", "pineapple"]]
count = -1
def indexer(fruits):
global count
count += 1
return count
foo_new = list(map(lambda fruits: list(map(indexer, fruits)), foo))
print(foo_new)
[[0, 1], [2], [3, 4, 5]]