交替插入一组元素

时间:2018-04-05 19:42:04

标签: python python-3.x list

有一个列表包含类似性质的元素(4 7,3 5等),我想以左右的顺序插入另一个列表()。

newlst = []
lst = [7, 7, 7, 7, 5, 5, 5, 3, 3, 3, 2, 2]

所以插入到newlst的第一件事就是7组:

newlst = [7,7,7,7]

随后,将5个组插入右侧列表中:

newlst = [7, 7, 7, 7, 5, 5, 5]

然后在左侧插入3组,然后在右侧插入2组。最终列表如下所示

newlst = [3, 3, 3, 7, 7, 7, 7, 5, 5, 5, 2, 2]

为了在左侧列表中添加列表中的元素,我这样做了:

for i in lst:
    lst.insert(0,i)
 else:
    lst.append(i)

insert方法将元素插入到0索引(列表的右侧)中,并追加在列表末尾添加元素(列表的左侧)。但是,我在将这组元素添加到newlst时遇到了问题。为此,我认为使用字典会是一个好主意。

myDict = {2: 2, 3: 3, 5: 3, 7: 4}

编辑:

for k, v in myDict.items():
    if k in lst:
        for i in range(v):
            lst.append(i)
        else:
            lst.insert(0,i)

这个词典的意图是每个键,我想插入键值“x”次,例如键7,将被插入4次:[7,7,7,7]。有没有办法在Python中实现这一点,所以我可以得到输出新列表:[3,3,3,7,7,7,7,5,5,5,2,2]?

3 个答案:

答案 0 :(得分:1)

您可以使用deque以及cyclegroupby

轻松完成此操作
from collections import deque
from itertools import groupby, cycle

#creates a deque object
d = deque()

#creates a repeating iterator to alternate function calls
c = cycle([d.extendleft, d.extend])

lst = [7, 7, 7, 7, 5, 5, 5, 3, 3, 3, 2, 2]
for _, items in groupby(lst):
    #calls the alternated function to extend the items 
    next(c)(items)

print(list(d))

>>> [3, 3, 3, 7, 7, 7, 7, 5, 5, 5, 2, 2]

答案 1 :(得分:1)

这是您的初始代码:

newlst = []
lst = [7, 7, 7, 7, 5, 5, 5, 3, 3, 3, 2, 2]
myDict = {2: 2, 3: 3, 5: 3, 7: 4}
for k, v in myDict.items():
    if k in lst:
        for i in range(v):
            lst.append(i)
        else:
            lst.insert(0,i)

这里有一些主要问题:

    根据定义,
  1. k始终位于lst。这意味着您的支票不是有效的替代方式。
  2. 您的数据已附加/添加到lst而不是newlst
  3. dict是哈希表。这意味着键的顺序几乎不会按照您定义它们的顺序。
  4. 第一项可以通过枚举来解决:

    for i, (k, v) in enumerate(myDict.items()):
        if i % 2:
            newlst = [k] * v + newlst
        else:
            newlst += [k] * v
    

    我修复了您要添加的列表,并使用[k] * v构建了前置/附加列表。 newlst += [k] * v相当于newlst.extend([k] * v)。但是,请记住newlst = [k] * v + newlst创建一个新的列表对象而不是就地连接。

    可以使用OrderedDict而不是常规dict来修复第三项:

    from collections import OrderedDict
    ...
    myDict = OrderedDict([(2, 2), (3, 3), (5, 3), (7, 4)])
    

    这将使键按您想要的顺序运行。事实上,您根本不需要手工构建myDict。您可以将OrderedDictCounter结合使用,以动态获得完全相同的结果。相关的配方在OrderedDict docs

    中给出
    from collections import Counter, OrderedDict
    ...
    class OrderedCounter(Counter, OrderedDict):
        def __repr__(self):
            return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
        def __reduce__(self):
            return self.__class__, (OrderedDict(self),)
    
    myDict = OrderedCounter(lst)
    

    所有这些都非常冗长而且效率不高。正如@Wondercricket's answer指出的那样,您可以使用itertools中的函数来使用生成器执行相同的任务。

答案 2 :(得分:0)

这是你想要做的?

list = [7, 7, 7, 7, 5, 5, 5, 3, 3, 3, 2, 2]

def list_to_answerlist(list, default=[]):
    if not list:
        return default
    else:
        result = []
        direction = True                      # Insert Direction: True = Insert Left / False = Insert Right
        actual_group = list[0]
        for element in list:
            if (element != actual_group):
                direction = not direction     # Change Insert Direction
                actual_group = element        # Update Actual Group
            if direction:                     # Insert Left
                result.insert(0,element)
            else:                             # Insert Right
                result.append(element)
        return result

new_list = list_to_answerlist(list)           # output = [3, 3, 3, 7, 7, 7, 7, 5, 5, 5, 2, 2]