列表理解以创建列表

时间:2018-08-24 18:27:12

标签: python list-comprehension

可以使用列表理解更紧凑地编码以下内容吗?

labels=[]
for i in range(10):
    labels=labels+[i]+9*['']
labels=labels+[10]

4 个答案:

答案 0 :(得分:2)

这是一种分解方法。

如果您查看循环的主体,可以将其重组为为每个数字生成一个子列表,然后将这些子列表组合在一起。

sublists = []
for i in range(10):
  sublists.append([i] + 9 * [''])

labels = []
for sublist in sublists:
  labels = labels + sublist

labels = labels + [10]

其中的第一部分获取一个数字列表,在每个数字上调用相同的函数,并生成一个结果列表。此操作为map(在许多语言中确实具有此名称)。第二部分获取一个列表列表,并将它们展平为一个大列表。许多语言都有“ concat”或“ flatten”操作,但是使用Python it can be a little clunky

from itertools import chain
sublists = map(range(10), lambda i: [i] + 9 * [''])
labels = list(chain.from_iterable(sublists))
labels = labels + [10]

map()调用特别容易转换为列表理解(或生成器理解)

from itertools import chain
sublists = [[i] + 9 * [''] for i in range(10)]
labels = list(chain.from_iterable(sublists))
labels = labels + [10]

因此,如果您希望将其变成单线,则可以

from itertools import chain
labels = list(chain.from_iterable([i] + 9 * [''] for i in range(10))) + [10]

对于完全不同的东西,您可能会使用生成器函数来使自己的工作更清晰。实际上,对于输入中的每个项目,您正在发出该项目,如果不是最后一个项目,则发出包含空字符串的九个列表。然后,您可以采用generator函数生成的序列并将其转换为列表。

def emit_with_blanks(iter):
  l = list(iter)
  for i, n in enumerate(l):
    yield [i]
    if i == len(l) - 1:
      break
    for _ in range(9):
      yield ['']

labels = list(emit_with_blanks(range(10))

这肯定会更长和更慢(在实践中应该没什么关系),但是比起单线来说,可以更容易地推断出它在做什么,特别是如果您六个月后回到那里并且试图记住代码的确切功能。

答案 1 :(得分:1)

这令人费解,但是如果您想要列表理解,这是一种实现方法:

[i for s in [[x] + 9*[''] if x < 10 else [x] for x in range(11)] for i in s]

演示:

>>> labels = [i for s in [[x] + 9*[''] if x < 10 else [x] for x in range(11)] for i in s]
>>> labels
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

通过比较方式:

>>> labels=[]
>>> for i in range(10):
...     labels=labels+[i]+9*['']
... 
>>> labels=labels+[10]
>>> labels
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

答案 2 :(得分:0)

这是您要查找的代码

labels=[j for i in range(10) for j in [i]+9*['']]+[10]

答案 3 :(得分:0)

对我来说,这就像“创建一个长度为101个元素的数组,其中每个项目的索引为10的非整数倍,则为空字符串,否则为索引除以10”。作为列表理解:

>>> ['' if i % 10 else i / 10 for i in xrange(101)]
[0, '', '', '', '', '', '', '', '', '', 1, '', '', '', '', '', '', '', '', '', 2, '', '', '', '', '', '', '', '', '', 3, '', '', '', '', '', '', '', '', '', 4, '', '', '', '', '', '', '', '', '', 5, '', '', '', '', '', '', '', '', '', 6, '', '', '', '', '', '', '', '', '', 7, '', '', '', '', '', '', '', '', '', 8, '', '', '', '', '', '', '', '', '', 9, '', '', '', '', '', '', '', '', '', 10]

也就是说,如果列表理解不是绝对的要求,那么我发现这样的事情要容易得多:

>>> y = []
>>> for i in xrange(10):
...     y.append(i)
...     y.extend([''] * 9)
...
>>> y.append(10)

(与您的原始方法几乎相同)