Вставьте символ новой строки каждые 64 символа с помощью Python

@wb помещает ссылку на Новые интерфейсы IReadOnlyList и IReadOnlyDictionary в комментариях, содержащих ответ:

Почему мы не изменили существующие интерфейсы для расширения интерфейсы только для чтения?

Похоже, разумное предположение, что оно работает, потому что интерфейсы только для чтения являются чисто подмножеством интерфейсов чтения и записи. К сожалению, это несовместимо, потому что на уровне метаданных каждый метод на каждом интерфейсе имеет свой собственный слот (который делает работу с явным интерфейсом работы).


Immo Landwerth | Команда .NET Framework (BCL) | http://blogs.msdn.com/b/bclteam/

blockquote>

Чтобы объяснить это более ясно:

Предположим, что a программа, написанная для .NET 4.0, содержит класс MyList, который реализует IList. Он явно не может реализовать IReadOnlyList, поскольку этот интерфейс не существует.

Теперь предположим, что системный администратор устанавливает .NET 4.5 и предположим, что .NET 4.5 сделал IList реализацию IReadOnlyList.

Если программа будет загружена, среда выполнения обнаружит, что MyList утверждает, что она реализована IList, но на самом деле не реализует все методы: она не реализует методы IReadOnlyList. Программа больше не будет работать.

Компилятор C # может сопоставлять методы по имени, но среда выполнения не делает этого. Так как .NET 4.5 должен был иметь обратную двоичную совместимость, интерфейсы не могли быть расширены для реализации других интерфейсов, даже если эти другие интерфейсы содержат строгое подмножество необходимых методов.

23
задан bignum 17 April 2010 в 07:54
поделиться

6 ответов

То же, что и в Perl, но с обратной косой чертой вместо доллара для доступа к группам:

s = "0123456789"*100 # test string
import re
print re.sub("(.{64})", "\\1\n", s, 0, re.DOTALL)

re.DOTALL эквивалентно Perl s / опция.

30
ответ дан 29 November 2019 в 00:43
поделиться

без регулярного выражения:

def insert_newlines(string, every=64):
    lines = []
    for i in xrange(0, len(string), every):
        lines.append(string[i:i+every])
    return '\n'.join(lines)

короче, но менее читабельно (imo):

def insert_newlines(string, every=64):
    return '\n'.join(string[i:i+every] for i in xrange(0, len(string), every))

Приведенный выше код предназначен для Python 2.x. Для Python 3.x вы хотите использовать range, а не xrange:

def insert_newlines(string, every=64):
    lines = []
    for i in range(0, len(string), every):
        lines.append(string[i:i+every])
    return '\n'.join(lines)

def insert_newlines(string, every=64):
    return '\n'.join(string[i:i+every] for i in range(0, len(string), every))
24
ответ дан gurney alex 29 November 2019 в 00:43
поделиться

взятие @ J.F. Решение Себастьяна на шаг впереди, и это почти преступно: -)

import textwrap
s = "0123456789"*100
print textwrap.fill(s, 64)

выглядят м ... без регулярных выражений! потому что, как вы знаете ... http://regex.info/blog/2006-09-15/247

спасибо за то, что познакомили нас с textwrap модуль ... хотя он находится в Python с 2.3, я никогда не знал об этом до сих пор (да, я признаю это публично) !!

9
ответ дан wescpy 29 November 2019 в 00:43
поделиться

Я предлагаю следующий метод:

"\n".join(re.findall("(?s).{,64}", s))[:-1]

Это более или менее не-RE метод, использующий преимущества механизма RE для цикла.

На очень медленном компьютере, который у меня есть в качестве домашнего сервера, это дает:

$ python -m timeit -s 's="0123456789"*100; import re' '"\n".join(re.findall("(?s).{,64}", s))[:-1]'
10000 loops, best of 3: 130 usec per loop

Метод AndiDog:

$ python -m timeit -s "s='0123456789'*100; import re" 're.sub("(?s)(.{64})", r"\1\n", s)'
1000 loops, best of 3: 800 usec per loop

2-й Гёрни Алекс / метод Майкла:

$ python -m timeit -s "s='0123456789'*100" '"\n".join(s[i:i+64] for i in xrange(0, len(s), 64))'
10000 loops, best of 3: 148 usec per loop

Я не считаю метод textwrap правильным для спецификации вопроса, поэтому я не буду его оценивать.

РЕДАКТИРОВАТЬ

Изменен ответ, потому что он был неправильным (позор мне!)

РЕДАКТИРОВАТЬ 2

Просто для удовольствия, метод RE-free с использованием itertools. Он оценивает треть по скорости, и это не Pythonic (слишком шумно):

"\n".join(
   it.imap(
     s.__getitem__,
     it.imap(
       slice,
       xrange(0, len(s), 64),
       xrange(64, len(s)+1, 64)
     )
   )
 )

$ python -m timeit -s 's="0123456789"*100; import itertools as it' '"\n".join(it.imap(s.__getitem__, it.imap(slice, xrange(0, len(s), 64), xrange(64, len(s)+1, 64))))'
10000 loops, best of 3: 182 usec per loop
3
ответ дан tzot 29 November 2019 в 00:43
поделиться

Я бы пошел с:

import textwrap
s = "0123456789"*100
print '\n'.join(textwrap.wrap(s, 64))
14
ответ дан 29 November 2019 в 00:43
поделиться

Крошечный, неприятный:

"".join(s[i:i+64] + "\n" for i in xrange(0,len(s),64))
5
ответ дан 29 November 2019 в 00:43
поделиться