这个问题已经有一个答案在这里:

如果我有顺序序列(也许一个单元组)我可以使用的迭代.链()平。但有时候我觉得我宁愿把它写作的理解。我只是不能弄清楚如何做到这一点。这是一个非常解释的情况下:

让我说我想要交换的元素,每一个对在一个序列。我用的字符串作为一种序列:

>>> from itertools import chain
>>> seq = '012345'
>>> swapped_pairs = zip(seq[1::2], seq[::2])
>>> swapped_pairs
[('1', '0'), ('3', '2'), ('5', '4')]
>>> "".join(chain(*swapped_pairs))
'103254'

我用拉链拉上甚至和奇切顺序,以交换对。但是我结束了一个清单元组,现在需要被夷为平地。所以我用链().有没有办法我可以表达这一理解,而不是?

如果你想以后你自己解决的基本问题交换要素对,来吧,我会上投票的任何东西告诉我一些新的东西。但我只会标记作为接受一个答案是针对我的疑问,即使回答是"不,你不能。".

有帮助吗?

解决方案

有理解?嗯...

>>> seq = '012345'
>>> swapped_pairs = zip(seq[1::2], seq[::2])
>>> ''.join(item for pair in swapped_pairs for item in pair)
'103254'

其他提示

最快的我发现是开始一个空阵列和延长:

In [1]: a = [['abc', 'def'], ['ghi'],['xzy']]

In [2]: result = []

In [3]: extend = result.extend

In [4]: for l in a:
   ...:     extend(l)
   ...: 

In [5]: result
Out[5]: ['abc', 'def', 'ghi', 'xzy']

这是超过两倍的速度的例子中,亚历克斯Martelli的企图上: 做一个平列出的清单列出了在蟒蛇

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 86.3 usec per loop

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99'  'b = []' 'extend = b.extend' 'for sub in l:' '    extend(sub)'
10000 loops, best of 3: 36.6 usec per loop

我来这是因为我有一种预感,在幕后,延长将分配适量的存储器清单,以及可能使用的一些低级别的代码移动项目。我不知道如果这是真的,但是谁在乎,这是速度更快。

通过这种方式,这只是一个直线加速:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]'  'b = []' 'extend = b.extend' 'for sub in l:' '    extend(sub)'
1000000 loops, best of 3: 0.844 usec per loop

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]' '[item for sublist in l for item in sublist]'
1000000 loops, best of 3: 1.56 usec per loop

你也可以使用 map(results.extend, a), 但这是较慢,因为它是建立其自己的名单的Nones.

它还提供了一些好处不使用功能性的程序。即

  • 你可以扩展现有名单而不是创建一个空的一个,
  • 你仍然可以明白的代码一目了然,分,几天甚至几个月以后。

通过这种方式,可能最好避免列表解析.小家伙是不是太坏,但在一般情况下列表推导不实际上你节省很多打字,但往往难以理解的,非常难以改变或重组(见过一个三级表的理解?). 谷歌的编码准则建议反对他们除了在简单案件。 我的意见是,他们只有在'扔掉的'代码,即代码在哪里提交人并不关心有关的可读性,或代码,是已知从未要求今后的维护。

比较这两种方式编写同样的事情:

result = [item for sublist in l for item in sublist]

与此:

result = []
for sublist in l:
    for item in sublist:
        result.append(item)

情况因人而异,但第一个停止我在我的轨道,我不得不去想它。在第二筑巢是由显而易见的压痕。

你可以使用的减少要达到你的目标:

In [6]: import operator
In [7]: a = [(1, 2), (2,3), (4,5)]
In [8]: reduce(operator.add, a, ())
Out[8]: (1, 2, 2, 3, 4, 5)

这回一组,而不是一个列表,因为要素在你原来清单元组获得连在一起。但是你可以很容易地建立一个列表,和参加方法接受组,太。

一个名单的理解是,通过的方式,并不正确的工具。基本上是一个名单的理解建立一个新列表说明如何要素的这个名单看起来应该喜欢的。你想要减少一个列表中的要素只有一个价值。

>>> a = [(1, 2), (3, 4), (5, 6)]
>>> reduce(tuple.__add__, a)
>>> (1, 2, 3, 4, 5, 6)

或者,是不可知的有关类型的内序列(只要他们所有的同):

>>> reduce(a[0].__class__.__add__, a)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top