说我有一个清单,
l = [1, 2, 3, 4, 5, 6, 7, 8]
我想获取任意元素的索引及其邻居的值。例如,
i = l.index(n)
j = l[i-1]
k = l[i+1]
但是,对于i == len(l) - 1
失败的边缘情况。所以我以为我只是把它包起来,
if i == len(l) - 1:
k = l[0]
else:
k = l[i+1]
有没有pythonic的方法来做到这一点?
答案 0 :(得分:33)
您可以使用模运算符!
i = len(l) - 1
jIndex = (i - 1) % len(l)
kIndex = (i + 1) % len(l)
j = l[jIndex]
k = l[kIndex]
或者,不那么冗长:
k = l[(i + 1) % len(l)]
答案 1 :(得分:25)
包装固定长度列表的最简单方法是使用%(modulo)运算符
list_element = my_list[idx % len(my_list)]
但无论如何看 http://docs.python.org/library/itertools.html
from itertools import cycle
for p in cycle([1,2,3]):
print "endless cycle:", p
答案 2 :(得分:6)
将值拟合到特定范围的典型方法是使用%
运算符:
k = l[(i + 1) % len(l)]
答案 3 :(得分:2)
如果你想把它作为一个类,我就掀起了这个快速的循环列表:
import operator
class CircularList(list):
def __getitem__(self, x):
if isinstance(x, slice):
return [self[x] for x in self._rangeify(x)]
index = operator.index(x)
try:
return super().__getitem__(index % len(self))
except ZeroDivisionError:
raise IndexError('list index out of range')
def _rangeify(self, slice):
start, stop, step = slice.start, slice.stop, slice.step
if start is None:
start = 0
if stop is None:
stop = len(self)
if step is None:
step = 1
return range(start, stop, step)
它支持切片,所以
CircularList(range(5))[1:10] == [1, 2, 3, 4, 0, 1, 2, 3, 4]
答案 4 :(得分:0)
如果你不想环绕, 最Pythonic的答案是使用切片。缺少用无替换的邻居。 E.g:
def nbrs(l, e):
i = l.index(e)
return (l[i-1:i] + [None])[0], (l[i+1:i+2] + [None])[0]
这是函数的工作方式:
>>> nbrs([2,3,4,1], 1)
(4, None)
>>> nbrs([1,2,3], 1)
(None, 2)
>>> nbrs([2,3,4,1,5,6], 1)
(4, 5)
>>> nbrs([], 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in nbrs
ValueError: 1 is not in list
答案 5 :(得分:0)
a = [2,3,5,7,11,13]
def env (l, n, count):
from itertools import cycle, islice
index = l.index(n) + len(l)
aux = islice (cycle (l), index - count, index + count + 1)
return list(aux)
表现如下
>>> env (a, 2,1)
[13, 2, 3]
>>> env (a,13,2)
[7, 11, 13, 2, 3]
>>> env (a,7,0)
[7]