在列表python中的元素左侧找到n个元素

时间:2018-11-04 17:06:46

标签: python

我有一个清单

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

我要编写一个函数 get_n_preceeding(a,list_of_numbers,n),该函数接受一个参数 a 并返回 n 个数字,在list_of_numbers中该数字之前。

例如:

get_n_preceeding(4, my_list, 2):

这应该返回列表中4之前的2个数字。 即ans = [2,3]

类似地,如果我想要2在1之前的数字,则其结果应为 [9,10]#我认为这是棘手的部分。

类似地,我希望编写另一个函数 get_n_succeeding(a,list_of_numbers,b)

get_n_succeeding(7, my_list, 2)  # This should return [8,9]

如果我使用get_n_succeeding(9, my_list, 2),它应该返回[10,1]。

我尝试使用 zip 运算符,但无法执行。

还有更好的方法吗?

5 个答案:

答案 0 :(得分:2)

我对get_n_preceeding使用列表推导,对后继使用for循环,如果后继索引超出范围,则减去数组的长度。

def get_n_preceeding(a: int, numbers: list, n: int = 2) -> list:
    start = numbers.index(a)
    return [numbers[start - n + x] for x in range(n)]


def get_n_succeeding(a: int, numbers: list, n: int = 2) -> list:
    start = numbers.index(a) + 1
    length = len(numbers)
    output = []
    for x in range(n):
        try:
            output.append(numbers[start + x])
        except IndexError:
            output.append(numbers[start + x - length])
    return output


my_list = list(range(1, 11))
print(get_n_preceeding(1, my_list, 2))  # -> [9, 10]
print(get_n_succeeding(9, my_list, 2))  # -> [10, 1]

答案 1 :(得分:1)

使用array.index()查找位置,然后相应地使用slice the array

def get_n_preceding(xs, x, n):
    end = xs.index(x)
    start = end - n
    ys = []
    for i in range(start, end):
        ys.append(xs[i % len(xs)])
    return ys

def get_n_succeeding(xs, x, n):
    start = xs.index(x) + 1
    end = start + n
    ys = []
    for i in range(start, end):
        ys.append(xs[i % len(xs)])
    return ys

get_n_preceding(list(range(10)), 1, 2)   #=> [10, 0]
get_n_preceding(list(range(10)), 5, 2)   #=> [3, 4]
get_n_succeeding(list(range(10)), 8, 2)  #=> [9, 0]
get_n_succeeding(list(range(10)), 5, 2)  #=> [6, 7]

如文档中所述,array.index()将找到第一个匹配的元素,并忽略以后的所有重复项。

答案 2 :(得分:0)

您可以使用.index()方法来查找a的索引。

aIndex = L.index(a)
preceding = []

for x in range(aIndex - n, aIndex): # Counting n numbers before a
if (aIndex - n) >= 0:               
    preceding.append(L[x])                     
else:                               
    aIndex = len(L)                 # "Turns around" the list if a - n < 0
    preceding.append(L[x])

print(preceding)

答案 3 :(得分:0)

您可以使用生成器和enumerate(iterable)

def get_n_preceeding(val,data,n=2, findall=False):
    found_at = []
    for pos,e in enumerate(data):
        if e == val:
            found_at.append(pos)
            if not findall:
                break

    ld = len(data)
    for p in found_at:
        circle = data + data + data
        yield circle[p-n+ld:p+ld]

测试:

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

print("Get first")
for part in get_n_preceeding(1,L,2):
    print(part)
print("Get all")
for part in get_n_preceeding(4,L,2,True):
    print(part) 

print("Get circle")
for part in get_n_preceeding(1,L,4):
    print(part)

输出:

Get first
[9, 10]

Get all
[2, 3]
[4, 5]
[7, 8]

Get circle
[8, 4, 9, 10]

答案 4 :(得分:0)

当您需要规则包装或重复表达式时,模数运算符(%)通常是一个不错的选择。例如,此解决方案针对边缘情况(例如n > len(lst))简单且健壮:

def get_n_preceding(val, lst, n):
    start = lst.index(val) - n
    return [lst[(start + x) % len(lst)] for x in range(n)]

def get_n_succeeding(val, lst, n):
    start = lst.index(val) + 1
    return [lst[(start + x) % len(lst)] for x in range(n)]

结果:

L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
get_n_preceding(4, L, n=2)  # [2, 3]
get_n_preceding(1, L, n=2)  # [9, 10]
get_n_preceding(3, [1, 2, 3], n=5)  # [1, 2, 3, 1, 2]

get_n_succeeding(7, L, n=2)  # [8, 9]
get_n_succeeding(9, L, n=2)  # [10, 1]
get_n_succeeding(3, [1, 2, 3], n=5)  # [1, 2, 3, 1, 2]