将子列表结构复制到Python中另一个相等长度的列表

时间:2018-02-15 15:51:45

标签: python list

说我有一个清单,

list1 = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra']

另一个,

list2 = [[True, True], [False], [True], [False]]

(你可以想象第二个清单是用动物作为家养宠物的itertools.groupby创建的。)

现在说我想给第一个列表提供与第二个列表相同的子列表结构。

list3 = [['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']]

我可能会这样做:

list3 = []
lengths = [len(x) for x in list2]
count = 0
for leng in lengths:
    templist = []
    for i in range(leng):   
        templist.append(list1[count])
        count += 1
    list3.append(templist)

我还没有完全调试,但我觉得应该可行。我的问题是,是否有更多的pythonic或简单的方法来做到这一点?这看起来有点令人费解,我不得不想象有一种更优雅的方式(也许是在永远不会给我留下深刻印象的itertools中)。

7 个答案:

答案 0 :(得分:11)

您可以简单地将next用于无法导入的解决方案:

list1 = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra']
list_1 = iter(list1)
list2 = [[True, True], [False], [True], [False]]
new_list2 = [[next(list_1) for _ in i] for i in list2]

输出:

[['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']]

但是,对于深度输入n级别,您可以使用递归:

list1 = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra']
list_1 = iter(list1)
list2 = [[True, [True, False]], [False], [[True]]]
def place_data(current):
   return [next(list_1) if isinstance(i, int) else place_data(i) for i in current]

print(place_data(list2))

输出:

[['Dog', ['Cat', 'Monkey']], ['Parakeet'], [['Zebra']]]

答案 1 :(得分:4)

iter list1 islicefrom itertools import islice list1 = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra'] list2 = [[True, True], [False], [True], [False]] it = iter(list1) list3 = [list(islice(it, len(el))) for el in list2] # [['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']] 每个list2必需的N个元素,例如:

d = {'A':[1,2], 'B':[0], 'c':[4]}

d.update({x: y+[0] for (x,y) in d.items() if len(y) < 2})

d
# {'A': [1, 2], 'B': [0, 0], 'c': [4, 0]}

答案 2 :(得分:3)

这是一种方式:

from itertools import accumulate

idx_acc = [0] + list(accumulate(map(len, list2)))
list1 = [list1[i:j] for i, j in zip(idx_acc, idx_acc[1:])]

# [['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']]

答案 3 :(得分:3)

class Agent: budget = None budget_left = None 允许您执行此操作,因为它会返回组以及键

itertools.groupby

另一个让人想到的选择是在列表上使用迭代器,比如

def is_pet(animal):
    return animal.lower() in ('dog', 'cat', 'parakeet')

animals = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra']
print([list(g) for k, g in itertools.groupby(animals, key=is_pet)])
# [['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']]

答案 4 :(得分:2)

这会根据50中相应列表的长度,将包含这些元素的列表替换为子列表。

list2

答案 5 :(得分:1)

如果你可以修改原始列表(如果没有,你可以随时复制),你可以在列表理解中使用pop()

list1 = ['Dog', 'Cat', 'Monkey', 'Parakeet', 'Zebra']
list2 = [[True, True], [False], [True], [False]]

list3 = [[list1.pop(0) for j in range(len(x))] for x in list2]
print(list3)
#[['Dog', 'Cat'], ['Monkey'], ['Parakeet'], ['Zebra']]

答案 6 :(得分:1)

有一种很好的递归方式适用于任意嵌套:

List<? extends Map<String, ?>>