Как добавить каждый n-й в последовательности?

Swift 4:

Общее решение, которое, наконец, работало для меня с html-кодом и символами новой строки и одиночными кавычками

extension String {
    var htmlDecoded: String {
        let decoded = try? NSAttributedString(data: Data(utf8), options: [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
            ], documentAttributes: nil).string

        return decoded ?? self
    }
}

Использование:

let yourStringEncoded = yourStringWithHtmlcode.htmlDecoded

Затем мне пришлось применить еще несколько фильтров, чтобы избавиться от single quotes (например: don't, hasn't, It's и т. д.), а также новые строковые символы, такие как \n

var yourNewString = String(yourStringEncoded.filter { !"\n\t\r".contains($0) })
yourNewString = yourNewString.replacingOccurrences(of: "\'", with: "", options: NSString.CompareOptions.literal, range: nil)
1
задан martineau 5 March 2019 в 01:53
поделиться

3 ответа

Интересной особенностью zip является возможность группировать входные данные в группы фиксированной длины без явного среза. Рецепт grouper позволяет преобразовывать в группы фиксированной длины, которые затем можно распаковать для следующего раунда zip, так что вы объединяете в пару первые элементы каждой группы:

[110 ]

Вы можете достичь того же результата с помощью:

>>> list(chain.from_iterable(lst[i::3] for i in range(3)))
['a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'b3', 'b4', 'c1', 'c2', 'c3', 'c4']

multi- zip просто переводит всю работу во встроенные модули (вообще без циклов Python). Кроме того, последний на два целых символа длиннее и кажется слишком похожим на ответ КориКрамера. :-) Тем не менее, последний лучше, если ваш ввод не четной длины; zip прекращает итерацию, когда самая короткая итерация исчерпана, в то время как itertools.zip_longest должен использовать значения заполнителя. Фактическая нарезка и сплющивание позволяют избежать этой проблемы.

0
ответ дан ShadowRanger 5 March 2019 в 01:53
поделиться

Вы можете пройти через последовательность с желаемыми смещениями, используйте itertools, чтобы сгладить обратно в одномерный список.

>>> import itertools
>>> d =  ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3']
>>> list(itertools.chain.from_iterable([d[::3], d[1::3], d[2::3]]))
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']

Вы также можете сделать что-то подобное, используя numpy, изменив форму массива, транспонировав, затем снова сплюснув

>>> import numpy as np
>>> d =  np.array(['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3'])
>>> np.reshape(d, (d.size//3, 3)).T.flatten()
array(['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'], dtype='<U2')
0
ответ дан CoryKramer 5 March 2019 в 01:53
поделиться

Допустим, вы хотите, чтобы интервал был n = 3

>>> a=[1,2,3,11,22,33,111,222,333]
>>> res=[]
>>> n=3
>>> for i in range(0,n):
...     for z in a[i::n]:
...         res.append(z)
... 
>>> 
>>> res
[1, 11, 111, 2, 22, 222, 3, 33, 333]

Более питонический

>>> a=['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'a3', 'b3', 'c3']
>>> res = [val for i in range(3) for val in a[i::3]]
>>> res
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']

, где a[i::3] просто перебирает список, начиная с i-го индекса, с шагом 3 .

0
ответ дан dnit13 5 March 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: