繁体   English   中英

如何使用 itertools 构建有序字符串列表?

[英]How to build a list of ordered strings with itertools?

我有一个 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

以普通方式使用的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']

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

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

你根本不需要 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']

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

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

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

现在只需使用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))

另一个使用itertools.accumulate

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM