How to build a list of growing initials of a string with itertools?

Question:

I have a Python string:"d4 d5 c4 e6 Nc3 Be7 Nf3 Nf6 Bg5 h6 Bf4 0-0 e3 Nbd7 g4 dxc4"

I want to split it into:

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

I’m not sure how to run itertools on it.

Asked By: SmallChess

||

Answers:

itertools.accumulate used in a plain manner is almost what you want:

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

If you want the spaces in there, you’ll need a custom accumulator function to add the spaces, e.g.:

>>> 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']
Answered By: ShadowRanger

This isn’t really an itertools problem. In Haskell, the function is called inits, but Python doesn’t have an equivalent built-in. We can write it ourselves.

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

Note that we return newly-constructed tuples so as not to share any data between iterations. We also yield the empty tuple first, since it’s a valid prefix of a list. If you don’t want that in your output, you can filter out the first element.

Now it’s just a bit of fixing up the data with join and split.

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))
Answered By: Silvio Mayolo

You don’t need itertools at all.

Try:

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']
Answered By: dawg

Another with itertools.accumulate:

list(map(' '.join, accumulate(zip(s.split()))))
Answered By: Kelly Bundy

Here one using list comprehension, regular expressions (from re import re.finditer as r ) and slicing (s is the string to process). This way all the splitting and joining again is not necessary:

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

With 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']
Answered By: bb1
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.