【问题标题】:Adding two items at a time in a list comprehension在列表理解中一次添加两个项目
【发布时间】:2013-10-19 12:46:08
【问题描述】:

我想一次将两个项目添加到列表理解中。一项是不变的。如何在列表理解中仅使用一个 for 循环而不使用其他功能来实现这一点。不使用任何导入的答案将受到青睐。

看看以下内容:

>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> sum([['^', char] for char in mystring.lower()], [])
['^', 'a', '^', 'b', '^', 'c', '^', 'e', '^', 'l', '^', 'k', '^', 'j', '^', 's', '^', 'd', '^', 'l', '^', 'h', '^', 'f', '^', 'w', '^', 'e', '^', 'h', '^', 's', '^', 'j', '^', 'd', '^', 'h', '^', 'f', '^', 'k', '^', 'h', '^', 'i', '^', 'u', '^', 'e', '^', 'h', '^', 'f', '^', 's', '^', 'd', '^', 'f']

我正在尝试在每个小写字母之前添加^ 字符的列表。在此示例中,您需要使用sum 来展平列表。但是,我的问题是,是否可以首先制作一个平面列表。上面的输出就是想要的输出。

就像在一个变量之前不断地附加一些东西,这个变量随着for循环的每次迭代而改变。不能在这里使用两个for 循环,因为那太简单了,例如:

mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
print [item for x in mystring.lower() for item in ['^', x]]

如果有人这样做:

>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> [['^', x] for x in mystring]
['^', 'a', '^', 'b', '^', 'c', '^', 'e', '^', 'l', '^', 'k', '^', 'j', '^', 's', '^', 'd', '^', 'l', '^', 'h', '^', 'f', '^', 'w', '^', 'e', '^', 'h', '^', 's', '^', 'j', '^', 'd', '^', 'h', '^', 'f', '^', 'k', '^', 'h', '^', 'i', '^', 'u', '^', 'e', '^', 'h', '^', 'f', '^', 's', '^', 'd', '^', 'f']

您在列表中获得列表。因此,有没有一种方法可以在列表推导中一次附加两个项目,而不必使用附加 for 循环或像 sum 这样的附加函数?我问这个,因为它很简单,但我找不到办法。如果有人尝试执行以下操作:

>>> ['^', x for x in mystring.lower()]
  File "<console>", line 1
    ['^', x for x in mystring.lower()]
              ^
SyntaxError: invalid syntax

尝试给出SyntaxError。那么,我所要求的在 Python 中是不可能做到的吗?使用 () 给了我一个元组列表。

我也尝试过使用splat/unpacking 运算符:

>>> [*['^', x] for x in mystring.lower()]
  File "<console>", line 1
    [*['^', x] for x in mystring.lower()]
     ^
SyntaxError: invalid syntax

但是如上所述,这也是一个语法错误。很抱歉编辑晚了,但我尝试了以下方法:

import itertools
mystring = "HELLOWORLD"
print(list(itertools.chain.from_iterable(('^', x) for x in mystring.lower())))

但以上内容仍然需要导入。

【问题讨论】:

标签: python list-comprehension


【解决方案1】:

您可以使用itertools.chain.from_iterable,这相当于嵌套列表理解版本,但效率稍高(对于大型列表):

>>> from itertools import chain
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> list(chain.from_iterable([['^', x] for x in mystring]))
['^', 'A', '^', 'B', '^', 'C', '^', 'E', '^', 'L', '^', 'K', '^', 'J', '^', 'S', '^', 'D', '^', 'L', '^', 'H', '^', 'F', '^', 'W', '^', 'E', '^', 'H', '^', 'S', '^', 'J', '^', 'D', '^', 'H', '^', 'F', '^', 'K', '^', 'H', '^', 'I', '^', 'U', '^', 'E', '^', 'H', '^', 'F', '^', 'S', '^', 'D', '^', 'F']

在 Python 3.3+ 中,您还可以在生成器函数中使用 yield from

>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF'
>>> def solve(strs):
...     for x in strs:
...         yield from ['^', x]
...         
>>> list(solve(mystring))
['^', 'A', '^', 'B', '^', 'C', '^', 'E', '^', 'L', '^', 'K', '^', 'J', '^', 'S', '^', 'D', '^', 'L', '^', 'H', '^', 'F', '^', 'W', '^', 'E', '^', 'H', '^', 'S', '^', 'J', '^', 'D', '^', 'H', '^', 'F', '^', 'K', '^', 'H', '^', 'I', '^', 'U', '^', 'E', '^', 'H', '^', 'F', '^', 'S', '^', 'D', '^', 'F']

【讨论】:

  • 没有itertools可以吗,因为我也试过了。
  • 我明白这一点,但是有没有办法每次都在列表理解中添加一个常量?这感觉就像它应该在那里。您正在使用导入,但 this 基本的东西不可用似乎很奇怪。我知道sum 效率低下,但除此之外,我只是想展示我的尝试。有没有办法以创造性的方式使用splat 运算符来获得我想要的?
  • @GamesBrainiac No splat operator 将无法在这里工作。
  • 那么,我猜如果没有导入或嵌套 for 循环就无法做到这一点?
【解决方案2】:

你可以从这个开始:

print list( '^'.join(mystring.lower()) )

给出:

['a', '^', 'b', '^', 'c', '^', ...]

所以这将给出所需的输出:

l = list( '^'.join(mystring.lower()) )
l.insert(0, '^')
print l

还有一种方式:

print [ y for x in zip(['^'] * len(mystring), mystring.lower()) for y in x ]

给出:

['^', 'a', '^', 'b', '^', 'c', ...

【讨论】:

  • 这个一个有趣的答案,但是^必须在第一个字母之前。
  • insert 符合您的预期
  • @GamesBrainiac,添加了纯理解解决方案
  • @perreal 使用 2 个for 循环。这更清楚[item for x in mystring.lower() for item in ['^', x]]
  • 如果^ 必须在第一个字母之前,list('^'+'^'.join(mystring.lower())) 有效并且可以等效地写作[x for x in '^' + '^'.join(mystring.lower())]
【解决方案3】:

如果有人在使用 pydash,您可以使用 flatten_deep。基本上,它递归地将您的列表扁平化到一个级别,以便您可以对多个列表进行列表理解。

>>> import pydash
>>> mystring = 'ABCELKJSDLHFWEHSJDHFKHIUEHFSDF' 
>>> pydash.flatten_deep([['^', x] for x in mystring])
['^', 'A', '^', 'B', '^', 'C', '^', 'E', '^', 'L', '^', 'K', '^', 'J', '^', 'S',           '^', 'D', '^', 'L', '^', 'H', '^', 'F', '^', 'W', '^', 'E', '^', 'H', '^', 'S', '^', 'J', '^', 'D', '^', 'H', '^', 'F', '^', 'K', '^', 'H', '^', 'I', '^', 'U', '^', 'E', '^', 'H', '^', 'F', '^', 'S', '^', 'D', '^', 'F']

【讨论】:

    【解决方案4】:

    好吧,在这种特殊情况下......

    >>> list('abcd'.replace('', '^')[ : -1])
    ['^', 'a', '^', 'b', '^', 'c', '^', 'd']
    >>>
    

    【讨论】:

      猜你喜欢
      • 2021-12-03
      • 1970-01-01
      • 2016-03-03
      • 2021-09-04
      • 1970-01-01
      • 2019-08-20
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多