【问题标题】:How to build a list of growing initials of a string with itertools?如何使用 itertools 构建字符串的增长首字母列表?
【发布时间】:2022-09-23 05:56:22
【问题描述】:

我有一个 Python 字符串:\"d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4\"

我想把它分成:

[\"d4\", \"d4 d5\", \"d4 d5 c4\", ... , \"d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4\"]

我不确定如何在上面运行itertools

  • 那不是“分裂”它,因为碎片重叠。试着把问题分解成合乎逻辑的步骤:如果你把它分成每一步(你知道怎么做吗?),你能想出一种方法来创造你想要的第一个价值吗?第二?将其概括为第 n 个?迭代以获得所有结果?
  • 我看不到使用itertools 的方法。在 Haskell 中,此函数将被称为 inits,但我在 Python 中没有看到等效函数。话虽如此,用 Python 自己编写它会很容易(尤其是使用生成器和yield)。
  • 您已经尝试过什么,您究竟需要什么帮助?为什么是itertools?如果这是作业,请阅读How to ask and answer homework questions。另见How to Ask。 (现在你已经得到了答案,也许这个评论没有实际意义,但我至少提到它以供将来参考。)

标签: python itertools


【解决方案1】:

你根本不需要 itertools。

尝试:

s="d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4"

li=s.split()

>>> [' '.join(li[0:i]) for i in range(1,len(li)+1)]
['d4', 'd4 d5', 'd4 d5 c4', 'd4 d5 c4 e6', 'd4 d5 c4 e6 Nc3', 'd4 d5 c4 e6 Nc3 Be7', 'd4 d5 c4 e6 Nc3 Be7 Nf3', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4', 'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4']

【讨论】:

    【解决方案2】:

    itertools.accumulate 以简单的方式使用是几乎你想要什么:

    >>> from itertools import accumulate
    >>> s = "d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4"
    >>> list(accumulate(s.split()))
    ['d4',
     'd4d5',
     'd4d5c4',
     'd4d5c4e6',
     'd4d5c4e6Nc3',
     'd4d5c4e6Nc3Be7',
     'd4d5c4e6Nc3Be7Nf3',
     'd4d5c4e6Nc3Be7Nf3Nf6',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf4',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf40-0',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf40-0e3',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf40-0e3Nbd7',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf40-0e3Nbd7g4',
     'd4d5c4e6Nc3Be7Nf3Nf6Bg5h6Bf40-0e3Nbd7g4dxc4']
    

    如果您想要其中的空格,则需要一个自定义累加器函数来添加空格,例如:

    >>> list(accumulate(s.split(), '{} {}'.format))
    ['d4',
     'd4 d5',
     'd4 d5 c4',
     'd4 d5 c4 e6',
     'd4 d5 c4 e6 Nc3',
     'd4 d5 c4 e6 Nc3 Be7',
     'd4 d5 c4 e6 Nc3 Be7 Nf3',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4',
     'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4']
    

    【讨论】:

    • 呃。我怎么忘了那个?
    • @KarlKnechtel:它是新的(ish),在 3.2 中添加,并且能够提供在 3.3 中添加的自定义累加器功能(直到 3.8 才最终添加 initial 参数以匹配 sum)。如果您在 2.x 时代记住了 itertools 模块并且没有注意,那么很容易忽略它。耸了耸肩
    • @KarlKnechtel 因为accumulate 是一个奇怪的词。在 C++ 中,它的意思是“折叠”。在 Python 中,它的意思是“扫描”(这是 OP 想要的)。在 Haskell 中,它是一种奇怪的索引向量更新操作。如果您像我一样使用其他语言,您的眼睛可能会忽略文档中的该功能。
    【解决方案3】:

    另一个itertools.accumulate

    list(map(' '.join, accumulate(zip(s.split()))))
    

    【讨论】:

    • 从来没有想过使用带有一个可迭代参数的zip 来将序列中的每个项目包装成一个单例元组。非常聪明。
    【解决方案4】:

    这不是真正的itertools 问题。在 Haskell 中,该函数称为 inits,但 Python 没有等效的内置函数。我们可以自己写。

    def inits(xs):
        yield ()
        acc = []
        for x in xs:
            acc.append(x)
            yield tuple(acc)
    

    请注意,我们返回新构建的元组,以免在迭代之间共享任何数据。我们还产生空元组第一的,因为它是列表的有效前缀。如果您不想在输出中使用它,则可以过滤掉第一个元素。

    现在只需用joinsplit 修复数据。

    my_string = "d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4"
    my_moves = my_string.split(" ")
    my_prefixes = map(" ".join, inits(my_moves))
    print(list(my_prefixes))
    

    【讨论】:

    • accumulate(zip(xs), initial=()) 将等同于您的 inits(xs)
    【解决方案5】:

    这里使用列表理解、正则表达式(from re import re.finditer as r)和切片(s 是要处理的字符串)。这样就不需要所有的拆分和加入:

    [s[0:m.start()] for m in r(" ",s)]+[s] 
    

    【讨论】:

      【解决方案6】:

      regex

      import regex
      
      s = "d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4"
      regex.findall(r"(?<=(?: |^)(.*)(?: |$))", s)
      
      ['d4',
       'd4 d5',
       'd4 d5 c4',
       'd4 d5 c4 e6',
       'd4 d5 c4 e6 Nc3',
       'd4 d5 c4 e6 Nc3 Be7',
       'd4 d5 c4 e6 Nc3 Be7 Nf3',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4',
       'd4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4']
      

      【讨论】:

        猜你喜欢
        • 2020-01-06
        • 1970-01-01
        • 2021-12-25
        • 2015-08-21
        • 1970-01-01
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多