Python присоединиться к результатам more_itertools.windowed - PullRequest
3 голосов
/ 08 апреля 2019

У меня следующая проблема: я пытаюсь создать так называемые «диграммы», например:

Если у меня есть слово foobar, я хочу получить список или генератор, например:["fo", "oo", "ob", "ba", "ar"].Идеальная функция для этого - more_itertools.windowed.Проблема в том, что он возвращает кортежи, как это:

In [1]: from more_itertools import windowed

In [2]: for i in windowed("foobar", 2):
   ...:     print(i)
   ...:
('f', 'o')
('o', 'o')
('o', 'b')
('b', 'a')
('a', 'r')

Конечно, я знаю, что могу .join() их, поэтому я бы получил:

In [3]: for i in windowed("foobar", 2):
   ...:     print(''.join(i))
   ...:
   ...:
fo
oo
ob
ba
ar

Мне просто интересно,где-то в itertools или more_itertools есть функция, которую я не вижу, которая делает именно это.Или есть более «питонный» способ сделать это вручную?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

Вы можете написать свою собственную версию widowed, используя нарезку.

def str_widowed(s, n):
    for i in range(len(s) - n + 1):
        yield s[i:i+n]

Это гарантирует, что получаемый тип совпадает с вводом, но больше не принимает неиндексированные итерации.

1 голос
/ 13 апреля 2019

more_itertools.windowed() является питоническим. Рассмотрим рецепт pairwise() itertools , который также дает кортежи:

def pairwise(iterable):
    "s -> (s0, s1), (s1, s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

Вы можете легко заменить windowed() на pairwise() и получить общие результаты - общее решение.


В качестве альтернативы вы можете нарезать строки, эмулируя парный принцип сжатия дублированных, но смещенных строк:

Код

s = "foobar"

[a + b for a, b in zip(s, s[1:])]
# ['fo', 'oo', 'ob', 'ba', 'ar']
...