【问题标题】:Get Next and Previous for every element in list python获取列表python中每个元素的下一个和上一个
【发布时间】:2018-01-03 09:24:24
【问题描述】:

我有一个清单:

day_list = [1,2,3,4,5,6]

我想编写一个函数,该函数将从此列表中获取任意数字 (no) 并返回下一个和上一个元素。

因此,例如,如果我通过 2,我应该得到 [1,3]1 是前一个元素,3 是下一个元素)。

但有一个问题:

如果 no = 1 前一个元素应该是 6,同样no = 6 下一个元素应该是 1

我想要类似的东西:

def getPrevNext(no):
    ....
    ....
    return [prev,next]

result = getPrevNext(2)  # result should be [1,3]
result2 = getPrevNext(5)  # result2 should be [4,5]
result3 = getPrevNext(1)  # result3 should be [6,2]
result4 = getPrevNext(6)  # result3 should be [5,1]

我试过了:

def dummy(no):
        if no == 1:
            prev_no = 6
            next_no = 2
        elif no == 6:
            prev_no = 5
            next_no = 1
        else:
            prev_no = no - 1
            next_no = no + 1
        return [prev_no,next_no]

但这似乎是一种非常幼稚和基本的方法。有没有更好的方法来做到这一点?

仅供参考不需要列出天数,这只是为了了解总数。

【问题讨论】:

  • 为什么 6 是 6 的下一个?
  • 您从未在dummy() 中访问过day_list
  • @timgeb 这是一个错字,因为在代码中 6 之后的下一项是 1。
  • @timgeb 6 的下一个是 1
  • 你应该创建一个圆表数据结构。

标签: python list


【解决方案1】:

@juanpa.arrivillaga's answer 很好地涵盖了这个问题的细节(这是一个关于如何使用模运算的问题)。但是,在访问 any 列表的上一个和下一个元素的一般情况下,我会这样做 -

def getPrevNext(l, no):
    i = l.index(no)
    return [l[i - 1], l[(i + 1) % len(l)]]

days = list(range(1, 7))

getPrevNext(days, 2)
[1, 3]

getPrevNext(days, 1)
[6, 2]

getPrevNext(days, 6)
[5, 1]

第一个表达式l[i - 1] 利用了python 使用负索引访问元素的能力。第二个表达式,l[(i + 1) % len(l)],是一个常见的循环列表访问习语。

要返回元组而不是列表,请在 return 语句中删除封闭的方括号 -

def getPrevNextAsTuple(l, no):
    i = l.index(no)
    return l[i - 1], l[(i + 1) % len(l)]

请注意,这不能处理no 不在列表中的可能性。在这种情况下,您将使用异常处理之类的东西来捕获任何引发的ValueErrors -

def getPrevNext(l, no):
    try:
        i = l.index(no)
    except ValueError:
        return None

    return l[i - 1], l[(i + 1) % len(l)]

【讨论】:

  • 你的意思是len(l)return 行。
  • 你正在返回一个元组。很抱歉吹毛求疵,这是一种很好的方式。我实际上是一个粉丝:)
【解决方案2】:

如果您使用 1-6 编码的“天”,请使用以下代码:

>>> def prev_next_day(day):
...     day -= 1
...     prev = ((day - 1) % 6) + 1
...     next_ = ((day + 1) % 6) + 1
...     return [prev, next_]
...
>>> prev_next_day(2)
[1, 3]
>>> prev_next_day(5)
[4, 6]
>>> prev_next_day(1)
[6, 2]
>>> prev_next_day(6)
[5, 1]

【讨论】:

  • 查找 prev 不需要 %6,因为访问权限为负。
  • @cᴏʟᴅsᴘᴇᴇᴅ 没有进行切片...原始问题描述具有误导性,这是关于前一天和后一天编码为 1-6 的问题,而不是一般列表。
  • @cᴏʟᴅsᴘᴇᴇᴅ 是的,最小值 = 1 和最大值 =6,这不是一般列表,您可以从函数中删除列表参数
  • @cᴏʟᴅsᴘᴇᴇᴅ 不,没有清单。本质上问题是如何进行模运算......
  • @cᴏʟᴅsᴘᴇᴇᴅ 好吧,标题具有高度误导性。 Classic XY-problem.
【解决方案3】:

您可以像这样使用slicing(也可以选择使用mod):

day_list = [1,2,3,4,5,6]

def get_prev_next(my_list, no):
  try:
    pointer = my_list.index(no)
  except ValueError:
    return []
  else:
    return [my_list[pointer-1], my_list[(pointer+1) % len(my_list)]]

示例:

# first element
print(get_prev_next(day_list, 1))   # -> [6, 2]

# last element
print(get_prev_next(day_list, 6))   # -> [5, 1]

# any other
print(get_prev_next(day_list, 3))   # -> [2, 4]

# non-existent element
print(get_prev_next(day_list, 98))  # -> []    

【讨论】:

    【解决方案4】:

    我会说以下作品:

    def getPrevNext(no):
        day_list = [1, 2, 3, 4, 5, 6]
        return([day_list[(no-2) % 6], day_list[(no) % 6]])
    

    根据你是否也只接受1 <= no <= 6,你可以像这样向这个函数添加一个条件:

    def getPrevNext(no):
        day_list = [1, 2, 3, 4, 5, 6]
        return([day_list[(no-2) % 6], day_list[(no) % 6]] if 1 <= no <= 6 else 0)
    

    【讨论】:

      【解决方案5】:
      def getem(lst,element):
      index=lst.index(element)
      try:
          if index!=0 and index!=(len(lst)-1):
              return [lst[index-1],lst[index+1]]
          else:
              if index==0:
                  return [lst[len(lst)-1],lst[index+1]]
              else:
                  return [lst[index-1],lst[0]]
      except Exception as e:
      print("element does not exists")
      

      试试这个函数,或者你可以在这个函数中使用循环链表,我已经模仿了这种行为

      【讨论】:

        【解决方案6】:

        您确定需要日期列表吗?

        def f(n):
            assert 0<n<7, "numbers should be between 1 and 6"
            return n-1 if n!=1 else 6, n+1 if n!=6 else 1
        f(1)
        #result (6, 2)
        

        【讨论】:

        • 不需要列出天数,只是为了了解总天数
        • 那么请验证我的代码是否满足您的要求。
        • 没关系。无论如何,到目前为止,您有 3 个答案。看看什么最适合你,或者结合答案;)
        【解决方案7】:

        我认为您提到的trick 以循环链表而闻名。如果我错了,请纠正我。

        day_list = [1,2,3,4,5,6] 
        def get_prev_next(elem):
            if elem not in day_list:
               return False     # element not found
            index = day_list.index(elem)
            return day_list[i - 1], l[(i + 1) % len(day_list)]
        

        【讨论】:

          【解决方案8】:

          对于previous,您可以利用这样一个事实,即在索引列表时,负索引意味着“从最后一个元素开始为负”。它有助于我将[-1] 视为“溢出”,这意味着转到第一个元素(索引0)并从最后一个元素开始计数。

          对于下一个,您可以使用modulo (%) 运算符,以确保将索引保持在0len(days_list) 之间。这仅在您要计算下一个数字的索引是列表的最后一个元素(索引5day_list 中的值6)的情况下才至关重要。只需将+1 添加到索引5 就会将您置于6,这不是有效的index。但随后你得到6 % 6 的模块并“变成”0

          day_list = [1, 2, 3, 4, 5, 6]
          
          
          def find(thing):
              position = day_list.index(thing)
              prev_pos = day_list[position - 1]
              next_pos = day_list[(position + 1) % len(day_list)]
              return prev_pos, next_pos
          
          
          if __name__ == "__main__":
              for i in range(1, 7):
                  print("prev_next %s: %s" % (i, find(i)))
          

          输出:

          prev_next 1: (6, 2)
          prev_next 2: (1, 3)
          prev_next 3: (2, 4)
          prev_next 4: (3, 5)
          prev_next 5: (4, 6)
          prev_next 6: (5, 1)
          

          【讨论】:

            猜你喜欢
            • 2011-12-31
            • 1970-01-01
            • 2019-05-20
            • 2022-12-01
            • 2014-04-20
            • 1970-01-01
            • 1970-01-01
            • 2020-07-31
            • 2015-08-09
            相关资源
            最近更新 更多