【问题标题】:Is there a "join" like function for generic lists in Python?Python中的通用列表是否有类似“加入”的函数?
【发布时间】:2014-04-01 13:55:22
【问题描述】:

在 Python 中,字符串列表可以通过以下方式连接在一起

','.join(['ab', 'c', 'def'])

但是我怎样才能轻松地加入数字列表或其他一些东西呢?像这样:

0.join([1, 2, 3])  --->  [1, 0, 2, 0, 3]

现在我必须这样做:

sum([[x, 0] for x in [1, 2, 3]], [])[:-1]

【问题讨论】:

  • 简短回答:不。
  • 请注意,您所描述的是不同的操作:str.join 通过交错和连接将字符串列表转换为字符串,您的广义连接会将 x 列表转换为通过仅交错而不连接的 x 列表。连接部分是join 是字符串方法而不是列表方法的全部原因。
  • 您可能希望[0].join([[1,2,3], [4,5], [6,7,8]]) 代表相同的功能。
  • 请注意 - 您的示例代码使用 sum() 加入列表 - 这通常是一个非常糟糕的主意,因为 sum() 没有针对该任务进行优化。查看 RemcoGerlich 的生成器,了解执行此操作的最佳方法。对于加入许多列表的一般情况 - 你想要itertools.chain()(如果你需要一个列表,请在结果生成器上使用list())。

标签: python


【解决方案1】:

你可以做一个:

def join_generator(joiner, iterable):
    i = iter(iterable)
    yield next(i)  # First value, or StopIteration

    while True:
       # Once next() raises StopIteration, that will stop this
       # generator too.
       next_value = next(i)
       yield joiner
       yield next_value

joined = list(join_generator(0, [1, 2, 3, 4]))

【讨论】:

  • 注意你最初可以只做yield next(i)(在进入while循环之前),不需要分配给next_value——除此之外,一个很好的实现。
  • 呸!我们需要更多的单线!每个人都喜欢单线! itertools.islice(itertools.chain.from_iterable(itertools.izip(itertools.repeat(joiner), iterable)), 1, None)
  • @DominicKexel 这不是一个单独的答案,因为?这与他发布的答案完全不同。
  • StopIteration 的语义在 Python 3.3 前后发生了变化。见stackoverflow.com/a/14183847/2160256。所以上面的答案不再起作用,但可以简单地修改:只需将 next 调用包装到 try/except 中,并在出现异常时返回。
【解决方案2】:

仅仅因为每个人都喜欢不可读的单行:

import itertools

def join(sep, col):
    return itertools.islice(itertools.chain.from_iterable(itertools.izip(itertools.repeat(sep), col)), 1, None)

P.S.:最好使用RemcoGerlich's answer。它更具可读性。

【讨论】:

    【解决方案3】:

    不是您想要的方式。您可以为总和编写一个 for 循环,或者您可以编写一个 for 循环并在您浏览列表时添加每个项目。否则,您将无法进行所需的调整。

    【讨论】:

      【解决方案4】:

      正如大家所说,join 是一个字符串方法而不是列表方法。

      但你总是可以这样做:

      [int(x) for x in '0'.join(map(str, [1, 2, 3]))]
      

      【讨论】:

      • 嗯,这依赖于所有数字都是个位数的假设?
      • 不错。但是如果元素是浮动的,它可能会失去精度。
      • 是的,依赖于很多假设,但做他想做的事
      • @tomaspdc 我很确定给出的场景是一个简化的场景——假设单个数字似乎不太可能是一个真实的案例。原始海报还说“或其他一些东西”。
      • 我同意,如果你想要一个通用的用途,我更喜欢@RemcoGerlich 解决方案。
      【解决方案5】:

      对于较新的python版本,应该这样做

      def join(joiner, iterable):
          """Small helper that does similar things as "foo".join("bar") """
          it = iter(iterable)
          head, tail = next(it, None), it
          if head is not None:
              yield head
      
          for item in tail:
              yield joiner
              yield item
      
      
      assert list(join("a", range(4))) == [0, "a", 1, "a", 2, "a", 3]
      assert list(join("a", [])) == []
      assert list(join("a", [0])) == [0]
      

      我错过了一些极端情况吗?

      【讨论】:

        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 1970-01-01
        • 2017-08-23
        • 2013-05-03
        • 2011-08-01
        • 2014-06-14
        • 2014-10-06
        • 1970-01-01
        相关资源
        最近更新 更多