之前:我读过Wrapping around a python list as a slice operation和wrapping 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>
答案 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)
希望它有意义!