如何包装字符串或数组并在Python中切片包装的字符串或数组?

时间:2018-02-05 15:24:22

标签: python arrays list

之前:我读过Wrapping around a python list as a slice operationwrapping around slices in Python / numpy

这个问题与这两个问题中的任何一个都不重复,因为这个问题是一个完全不同的问题。因此,请停止投票,不要将其标记为重复。在第一个提到的线程中,“换行”意味着不同的东西。对于第二个提到的线程,它们处理ndarray并且只能用于整数。

真实问题: 如何将字符串或数组从一个点切割到另一个点,并在它们之间有一个结尾?

基本上,我们想要做这样的事情,

n = whatever we want
print(string[n-5:n+6])

以上代码可能看起来很正常。但它在边缘附近(靠近字符串/数组的开头或字符串/数组的末尾)不起作用。因为Python的切片不允许切片到数组的末尾并从头开始。如果n小于5或长度大于n + 6的字符串长度怎么办?

这是一个更好的例子,考虑到我们有

array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']

我们希望打印一个元素,其中最近的两个邻居在字符串中,用于数组中的所有元素

print("Two neighbors:")
for i, x in enumerate(array):
    print(array[i-1] + array[i] + array[(i+1)%len(array)])

输出:

Two neighbors:
kab
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jka

到目前为止一切顺利,让我们与四个邻居一起做。

print("Four neighbors:")
for i, x in enumerate(array):
    print(array[i-2] + array[i-1] + array[i] + array[(i+1)%len(array)] + array[(i+2)%len(array)])

输出:

Four neighbors:
jkabc
kabcd
abcde
bcdef
cdefg
defgh
efghi
fghij
ghijk
hijka
ijkab

你可以看到它的发展方向,因为所需的邻居数量增长,我们必须逐个输出它们的次数会增加。

有没有办法代替s [n-3] + s [n-2] + s [n-1] + s [n] + s [n + 1] + s [n + 2] + s [n + 3],我们可以做类似s [n-3:n + 4]的事情吗?

请注意,s [n-3:n] + s [n:(n + 4)%len(s)]在边缘不起作用。

注:

对于上面的特定示例,可以做一个3 *数组或在前面和后面添加一些元素来基本上“填充”它。

然而,这种类型的答案需要花费一些内存,而且当我们想要将它包裹很多时,它们就无法工作。

考虑以下内容,

# len(string) = 10
# n = 0 or any number we want
print(string[n-499:n+999])

如果开始和结束索引可以灵活而不是相互镜像(例如,字符串[n-2:n + 9]而不是字符串[n-3:n + 4]),那就更好了。< / p>

4 个答案:

答案 0 :(得分:1)

这可以给出想法。唯一要检查的是你的间隔中的顺序。适用于任何n

array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']

def print_neighbors(n_neighbors):
    for idx in range(len(array)):
        start = (idx- n_neighbors//2) % len(array)
        end = (idx+n_neighbors//2) % len(array) + 1
        if start > end:
            print(''.join(array[start:] + array[:end]))
        else:
            print(''.join(array[start:end]))

>>> print_neighbors(6)

ijkabcd
jkabcde
kabcdef
abcdefg
bcdefgh
cdefghi
defghij
efghijk
fghijka
ghijkab
hijkabc

答案 1 :(得分:1)

不使用过多内存的解决方案如下

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def get_sequences(a_list, sequence_length):
    sequences = []
    for i in range(len(my_list)):
        sequences.append("".join(str(my_list[(x + i) % len(my_list)]) for x in range(sequence_length)))
    return sequences

print(get_sequences(my_list, 2))
print(get_sequences(my_list, 3))

将输出

['12', '23', '34', '45', '56', '67', '78', '89', '91']
['123', '234', '345', '456', '567', '678', '789', '891', '912']

这很好,因为它可以随处使用发电机。

答案 2 :(得分:0)

您可以创建一个类来包装您的原始迭代:

class WrappingIterable():
     def __init__(self, orig):
         self.orig=orig
     def __getitem__(self, index):
         return self.orig[index%len(self.orig)]
     def __len__(self):
         return len(self.orig)


>>> w = WrappingIterable("qwerty")
>>> for i in range(-2, 8):
...     print(w[i])
t
y
q
w
e
r
t
y
q
w

答案 3 :(得分:0)

对于此特定问题,您可以使用以下代码段:

def print_neighbors(l, n):
   wrapped = l[-(n//2):] + l + l[:(n//2)]
   for i in range(len(l)):
     print(''.join(wrapped[i:i+n+1]))

l = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
print_neighbors(l, 2)
print_neighbors(l, 4)

希望它有意义!