【问题标题】:divide two lists evenly over 3 other lists将两个列表平均分配在其他 3 个列表上
【发布时间】:2018-04-23 17:48:23
【问题描述】:

我正在努力想出一个有效但简单的解决方案来解决以下问题:

我有两个字典列表:

list_dicts_1 = [
{"name": "Suarez", "footed": "right-footed", "color": "black"}
{"name": "Suarez2", "footed": "right-footed2", "color": "black2"}
{"name": "Suarez3", "footed": "right-footed3", "color": "black3"}
{"name": "Suarez4", "footed": "right-footed4", "color": "black4"}
{"name": "Suarez5", "footed": "right-footed5", "color": "black5"}
{"name": "Suarez6", "footed": "right-footed6", "color": "black6"}
]


list_dicts_2 = [
{"name": "Coutinho", "footed": "left-footed", "color": "orange"}
{"name": "Coutinho2", "footed": "left-footed1", "color": "orange2"}
{"name": "Coutinho3", "footed": "left-footed2", "color": "orange3"}
{"name": "Coutinho4", "footed": "left-footed4", "color": "orange4"}
{"name": "Coutinho5", "footed": "left-footed5", "color": "orange5"}
{"name": "Coutinho6", "footed": "left-footed6", "color": "orange6"}
]

我想遍历这些字典列表并将它们分配给 3 个空列表:

list_1 = []
list_2 = []
list_3 = [] 

想要的输出:

list_1 = [
{"name": "Suarez", "footed": "right-footed", "color": "black"}, 
{"name": "Suarez4", "footed": "right-footed4", "color": "black4"},
{"name": "Coutinho", "footed": "left-footed", "color": "orange"},
{"name": "Coutinho4", "footed": "left-footed4", "color": "orange4"}
]        

list_2 = [
{"name": "Suarez2", "footed": "right-footed2", "color": "black2"}, 
{"name": "Suarez5", "footed": "right-footed5", "color": "black5"},
{"name": "Coutinho2", "footed": "left-footed2", "color": "orange2"},
{"name": "Coutinho5", "footed": "left-footed5", "color": "orange5"}
]

list_3 = [
{"name": "Suarez3", "footed": "right-footed3", "color": "black3"}, 
{"name": "Suarez6", "footed": "right-footed6", "color": "black6"},
{"name": "Coutinho3", "footed": "left-footed3", "color": "orange3"},
{"name": "Coutinho6", "footed": "left-footed6", "color": "orange6"}
]

我想将 dicts 列表平均分配到 3 个空列表中。 dicts 列表中的每个项目只能在空列表中出现一次。所以字典列表的第一行应该放在 list_1 中。然后字典列表的第二行应该进入 list_2 等,直到字典列表中没有任何内容。

有没有简单的方法来实现这一点?

【问题讨论】:

  • 这个样本的期望输出是什么?
  • 编辑主帖。
  • 伙伴你不需要这样做。你只需要一个列表和一个字典:list_1 = [{"name": "Messi", "footed": "left-footed", "color": "doesn't matter"}].

标签: python list loops dictionary for-loop


【解决方案1】:

迭代器在这里非常有用:您可以使用itertools.cycle 来获得一个迭代器,它可以无限循环list_1list_2list_3。然后简单地遍历list_dicts_1list_dicts_2 中的字典并将它们附加到您从cycle 获得的列表中:

import itertools

list_1, list_2, list_3 = lists = [], [], []
# make an iterator that endlessly loops over list_1, list_2 and list_3
itr = itertools.cycle(lists)

# loop over the dicts
for dic in itertools.chain(list_dicts_1, list_dicts_2):
    # and append the dict to the next list
    next(itr).append(dic)

我使用itertools.chainlist_dicts_1list_dicts_2 组合成一个可迭代对象,并使用next 函数手动推进cycle 迭代器。

结果:

>>> list_1
[{'name': 'Suarez', 'footed': 'right-footed', 'color': 'black'},
 {'name': 'Suarez4', 'footed': 'right-footed4', 'color': 'black4'},
 {'name': 'Coutinho', 'footed': 'left-footed', 'color': 'orange'},
 {'name': 'Coutinho4', 'footed': 'left-footed4', 'color': 'orange4'}]
>>> list_2
[{'name': 'Suarez2', 'footed': 'right-footed2', 'color': 'black2'},
 {'name': 'Suarez5', 'footed': 'right-footed5', 'color': 'black5'},
 {'name': 'Coutinho2', 'footed': 'left-footed1', 'color': 'orange2'},
 {'name': 'Coutinho5', 'footed': 'left-footed5', 'color': 'orange5'}]
>>> list_3
[{'name': 'Suarez3', 'footed': 'right-footed3', 'color': 'black3'},
 {'name': 'Suarez6', 'footed': 'right-footed6', 'color': 'black6'},
 {'name': 'Coutinho3', 'footed': 'left-footed2', 'color': 'orange3'},
 {'name': 'Coutinho6', 'footed': 'left-footed6', 'color': 'orange6'}]

另一种选择是将两个输入列表连接成一个巨大的列表,然后对其进行切片:

list_ = list_dicts_1 + list_dicts_2
list_1 = list_[::3]
list_2 = list_[1::3]
list_3 = list_[2::3]

但是,连接列表的成本有些高,因此如果您的列表非常大,则应避免使用。

【讨论】:

  • 非常感谢。出于好奇,有没有办法在没有 itertools 库的情况下实现这一目标?
  • @adbSOeh 有,而且它实际上并不像我最初想象的那么难看。我更新了我的答案。
  • 很好,我真的很喜欢切片方法。我真的想多了。
  • zip(*zip(*[iter(list_dicts_1+list_dicts_2)]*3))
  • @JoranBeasley 请不要。难以理解的单线在这里是禁区。把它带到可以被否决的地方:P
【解决方案2】:

您可以使用while 循环这样做:

while True:
    try:
        list_1.append(dicts[0])
        del dicts[0]

        list_2.append(dicts[0])
        del dicts[0]

        list_3.append(dicts[0])
        del dicts[0]

    except IndexError:
        break

编辑:

也可以使用for 循环来完成!

for i in range(len(dicts)//3):
     list_1.append(dicts[0])
     del dicts[0]
     list_1.append(dicts[0])
     del dicts[0]
     list_1.append(dicts[0])
     del dicts[0]

编辑 2:

它可以做得更好,对于初学者来说仍然很容易理解

for i in range(len(dicts)//3):
    list_1.append(dicts[i*3])
    list_1.append(dicts[i*3+1])
    list_1.append(dicts[i*3+2])

【讨论】:

  • 有趣的方法!
  • 这太棒了。对于初学者来说非常容易阅读和理解。非常感谢。
  • 重复删除列表的第一个元素具有可怕的运行时间复杂度。您应该将其转换为 deque 或将其反转并从另一端删除,或者仅使用迭代器而不是删除。
猜你喜欢
  • 1970-01-01
  • 2014-05-19
  • 1970-01-01
  • 2020-11-30
  • 2012-10-08
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多