使用列表理解有条件地将 1 或 2 个项目添加到列表中
Conditionally adding 1 or 2 items into a list using a list comprehension
有没有一种方法可以使用列表推导式根据某些条件仅使用一个 for 循环将一个或两个项目插入到列表中?
例如,如果我想遍历 n 个数字,如果一个数字是偶数则插入它,如果一个数字是奇数则插入它并插入它加 1。
到目前为止,我所得到的只是使用嵌套列表理解和三个 for 循环,而这应该只用一个 for 循环来完成:
new_lst = [num for sublist in [[i] if i%2 == 0 else [i,i+1] for i in range(n)] for num in sublist]
一个for循环的正常方式是这样的:
new_list = []
for i in range(n):
new_lst.append(i)
if i % 2 == 1:
new_lst.append(i+1)
非常感谢任何帮助,谢谢!
我会使用非常高效的生成器来解决这个问题:
def gen(n):
for i in range(n):
yield i
if i%2:
yield i+1
list(gen(n))
# [0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20]
如果你真的想要一个one-liner(不是严格意义上的列表理解):
from itertools import chain
n = 20
list(chain.from_iterable([i, i+1] if i%2 else [i] for i in range(n)))
# [0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20]
我会使用两个单独的 list
理解来解决这个问题。这应该会略微提高时间复杂度,降低到 O(N) + O(N/2)
,从而简化为 O(N)
.
from itertools import chain
from timeit import timeit
def gen(n):
for i in range(n):
yield i
if i % 2:
yield i + 1
def gen2(n):
return [i for i in range(n + 1)] + [i for i in range(2, n, 2)]
def gen2_in_order(n):
return sorted([i for i in range(n + 1)] + [i for i in range(2, n, 2)])
def gen3(n):
return list(chain.from_iterable([i, i + 1] if i % 2 else [i] for i in range(n)))
def gen4(n):
return [num for i in range(n) for num in range(i, i + 1 + i % 2)]
assert list(gen(1000)) == gen2_in_order(1000) == gen3(1000) == gen4(1000)
print('generator: ', timeit('gen(n)', globals=globals(), setup='n=100'))
print('generator (list): ', timeit('list(gen(n))', globals=globals(), setup='n=100'))
print('list comp: ', timeit('gen2(n)', globals=globals(), setup='n=100'))
print('list comp (sorted): ', timeit('gen2_in_order(n)', globals=globals(), setup='n=100'))
print('from_iter: ', timeit('gen3(n)', globals=globals(), setup='n=100'))
print('list comp (single): ', timeit('gen4(n)', globals=globals(), setup='n=100'))
我的 Mac 结果:
generator: 0.08834924991242588
generator (list): 5.09551537502557
list comp: 2.2710815421305597
list comp (sorted): 3.3015330410562456
from_iter: 7.440466790925711
list comp (single): 12.89962362498045
有没有一种方法可以使用列表推导式根据某些条件仅使用一个 for 循环将一个或两个项目插入到列表中?
例如,如果我想遍历 n 个数字,如果一个数字是偶数则插入它,如果一个数字是奇数则插入它并插入它加 1。
到目前为止,我所得到的只是使用嵌套列表理解和三个 for 循环,而这应该只用一个 for 循环来完成:
new_lst = [num for sublist in [[i] if i%2 == 0 else [i,i+1] for i in range(n)] for num in sublist]
一个for循环的正常方式是这样的:
new_list = []
for i in range(n):
new_lst.append(i)
if i % 2 == 1:
new_lst.append(i+1)
非常感谢任何帮助,谢谢!
我会使用非常高效的生成器来解决这个问题:
def gen(n):
for i in range(n):
yield i
if i%2:
yield i+1
list(gen(n))
# [0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20]
如果你真的想要一个one-liner(不是严格意义上的列表理解):
from itertools import chain
n = 20
list(chain.from_iterable([i, i+1] if i%2 else [i] for i in range(n)))
# [0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20]
我会使用两个单独的 list
理解来解决这个问题。这应该会略微提高时间复杂度,降低到 O(N) + O(N/2)
,从而简化为 O(N)
.
from itertools import chain
from timeit import timeit
def gen(n):
for i in range(n):
yield i
if i % 2:
yield i + 1
def gen2(n):
return [i for i in range(n + 1)] + [i for i in range(2, n, 2)]
def gen2_in_order(n):
return sorted([i for i in range(n + 1)] + [i for i in range(2, n, 2)])
def gen3(n):
return list(chain.from_iterable([i, i + 1] if i % 2 else [i] for i in range(n)))
def gen4(n):
return [num for i in range(n) for num in range(i, i + 1 + i % 2)]
assert list(gen(1000)) == gen2_in_order(1000) == gen3(1000) == gen4(1000)
print('generator: ', timeit('gen(n)', globals=globals(), setup='n=100'))
print('generator (list): ', timeit('list(gen(n))', globals=globals(), setup='n=100'))
print('list comp: ', timeit('gen2(n)', globals=globals(), setup='n=100'))
print('list comp (sorted): ', timeit('gen2_in_order(n)', globals=globals(), setup='n=100'))
print('from_iter: ', timeit('gen3(n)', globals=globals(), setup='n=100'))
print('list comp (single): ', timeit('gen4(n)', globals=globals(), setup='n=100'))
我的 Mac 结果:
generator: 0.08834924991242588
generator (list): 5.09551537502557
list comp: 2.2710815421305597
list comp (sorted): 3.3015330410562456
from_iter: 7.440466790925711
list comp (single): 12.89962362498045