【问题标题】:Insert element to list based on previous and next elements根据上一个和下一个元素将元素插入到列表中
【发布时间】:2016-07-09 19:41:19
【问题描述】:

我正在尝试将新元组添加到元组列表(按元组中的第一个元素排序),其中新元组包含列表中前一个元素和下一个元素的元素。

例子:

oldList = [(3, 10), (4, 7), (5,5)]
newList = [(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)]

(4,10) 是在 (3,10) 和 (4,7) 之间构造和添加的。

Construct (x,y) from (a,y) and (x,b)

我尝试使用 enumerate() 在特定位置插入,但这并不能真正让我访问下一个元素。

【问题讨论】:

  • 用户的输入是什么?新榆树的新位置?
  • 用户只提供初始的“oldList”。然后在每两个旧元素之间,在现有两个元素的基础上添加一个新元素。

标签: python list


【解决方案1】:
oldList = [(3, 10), (4, 7), (5,5)]

def pair(lst):
    # create two iterators
    it1, it2 = iter(lst), iter(lst)
    # move second to the second tuple
    next(it2)
    for ele in it1:
        # yield original
        yield ele
        # yield first ele from next and first from current
        yield (next(it2)[0], ele[1])

这会给你:

In [3]: oldList = [(3, 10), (4, 7), (5, 5)]

In [4]: list(pair(oldList))
Out[4]: [(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)]

显然我们需要做一些错误处理来处理不同的可能情况。

如果您愿意,也可以使用单个迭代器:

def pair(lst):
    it = iter(lst)
    prev = next(it)
    for ele in it:
        yield prev
        yield (prev[0], ele[1])
        prev = ele
    yield (prev[0], ele[1])

您可以使用itertools.tee 代替调用iter:

from itertools import tee
def pair(lst):
    # create two iterators
    it1, it2 = tee(lst)
    # move second to the second tuple
    next(it2)
    for ele in it1:
        # yield original
        yield ele
        # yield first ele from next and first from current
        yield (next(it2)[0], ele[1])

【讨论】:

  • 非常感谢,这就像一个魅力。虽然它适用于我当前的列表,但错误处理将如何改进此方法?
  • @SilviuTofan,真的只是像捕捉空/单个元组等。你如何处理它取决于你想在这些情况下发生什么
【解决方案2】:

您可以使用列表推导式和itertools.chain():

>>> list(chain.from_iterable([((i, j), (x, j)) for (i, j), (x, y) in zip(oldList, oldList[1:])])) + oldList[-1:]
[(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)]

【讨论】:

  • 也感谢您的回答!我只是开始实施另一个,因为它发布的时间比你的稍早。
【解决方案3】:

我自己不是单行(或复杂性)的忠实拥护者,我会为您的问题提出一个非常明确且易读(通常是一件好事!)的解决方案。

所以,采用非常简单的方法,您可以这样做:

def insertElements(oldList):
    """
    Return a new list, alternating oldList tuples with 
    new tuples in the form (oldList[i+1][0],oldList[i][1])
    """
    newList = []
    for i in range(len(oldList)-1):
      # take one tuple as is
      newList.append(oldList[i])
      # then add a new one with items from current and next tuple
      newList.append((oldList[i+1][0],oldList[i][1]))
    else:
      # don't forget the last tuple
      newList.append(oldList[-1])
    return newList

oldList = [(3, 10), (4, 7), (5, 5)]
newList = insertElements(oldList)

这将在newList 中为您提供所需的结果:

print(newList)
[(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)]

与其他更复杂(并且内存效率更高!)的解决方案(例如使用生成器)相比,这并不长多少代码,而且我认为它比复杂的单行代码更容易阅读。此外,向这个简单的函数添加一些检查也很容易(比如确保你有一个元组列表)。

除非您已经知道需要优化这段特定的代码(假设这是一个更大项目的一部分),否则应该是 good enough。同时:易于实现、易于阅读、易于解释、易于维护、易于扩展、易于重构等。

注意:在许多方面,您问题的所有其他先前答案也比这个简单的答案更好。只是想给你另一个选择。希望这可以帮助。

【讨论】:

  • 谢谢,我也非常感谢这个答案,它使一段代码非常易于阅读和实现!
猜你喜欢
  • 2016-03-29
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2017-01-15
相关资源
最近更新 更多