为了账号安全,请及时绑定邮箱和手机立即绑定

弄平序列序列的理解?

/ 猿问

弄平序列序列的理解?

SMILET 2019-11-19 15:40:08

如果我有序列的序列(可能是一个元组列表),则可以使用itertools.chain()进行展平。但是有时候我觉得我宁愿把它写成一种理解。我只是不知道该怎么做。这是一个很容易理解的情况:


假设我要交换序列中每对的元素。我在这里使用字符串作为序列:


>>> 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'

我在序列的偶数和奇数切片上使用zip来交换对。但是,我最终得到了一个元组列表,现在需要对其进行展平。所以我使用chain()。有什么办法可以代替我理解吗?


如果您想发布自己的解决交换元素对基本问题的解决方案,请继续,我将投票给所有教给我新知识的东西。但是,即使答案为“不,您不能”,我也只会将针对我的问题的答案标记为已接受。


查看完整描述

3 回答

?
UYOU

有理解力吗?好...


>>> seq = '012345'

>>> swapped_pairs = zip(seq[1::2], seq[::2])

>>> ''.join(item for pair in swapped_pairs for item in pair)

'103254'


查看完整回答
反对 回复 2019-11-19
?
函数式编程

我发现最快的方法是从一个空数组开始并扩展它:


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']

这是Alex Martelli尝试以下示例的速度的两倍以上:从Python列表列表中生成一个平面列表


$ 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

我之所以提出这个建议,是因为我有一种预感,在幕后,extend会为列表分配合适的内存量,并且可能会使用一些低级代码来移入项目。我不知道这是否成立,但是谁在乎,它会更快。


顺便说一下,这只是线性加速:


$ 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),但是这样做较慢,因为它正在构建自己的“无”列表。


它还为您提供了不使用函数式编程的一些好处。即


您可以扩展现有列表,而不用创建一个空列表,

您仍然可以在几分钟,几天甚至几个月后一目了然地了解代码。

顺便说一句,最好避免列表理解。较小的列表还不错,但是总的来说列表理解实际上并不能为您节省很多打字时间,但是通常更难以理解,也很难更改或重构(曾经见过三层列表理解吗?)。Google编码准则建议不要这样做,除非是简单情况。我的意见是,它们仅在“扔掉”的代码中有用,例如,编写者不关心可读性的代码,或不再需要将来维护的代码。


比较这两种编写相同内容的方式:


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

有了这个:


result = []

for sublist in l:

    for item in sublist:

        result.append(item)

YMMV,但是第一个让我停滞不前,我不得不考虑一下。在第二个中,从缩进中可以明显看出嵌套。


查看完整回答
反对 回复 2019-11-19
?
幕布斯6054654

您可以使用reduce达到您的目标:


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)

这将返回一个元组而不是一个列表,因为原始列表中的元素是被串联的元组。但是您可以轻松地从中建立一个列表,join方法也可以接受元组。


顺便说一句,列表理解不是正确的工具。基本上,列表理解通过描述此列表的元素外观来构建新列表。您希望将元素列表减少为一个值。


查看完整回答
反对 回复 2019-11-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信