【问题标题】:Create a dictionary from a list of lists with certain criteria [closed]从具有特定条件的列表列表中创建字典 [关闭]
【发布时间】:2020-11-27 20:55:15
【问题描述】:

我有一个列表如下:

l1=[['a1','a2','a3'],['b1','b2'],['c1','a1']]

我想要一个字典列表如下:

[{"start":"a1","end":"ä2"},
 {"start":"a2","end":"a3"},
 {"start":"a3","end":"a1"},
 {"start":"b1","end":"b2"},
 {"start":"c1","end":"a1"}
]

我尝试了以下代码并得到了索引超出范围的异常:

for val in list_listedges:
    for i in range(0,len(val)):
        dict_edges["start"]=val[i]
        dict_edges["end"]=val[i+1]

我正在寻找可以产生相同结果的有效解决方案或上述代码的增强。此外,3 不是一个固定数字。它也可能是 4 或 5。在这种情况下,我需要所有元素互相配对

【问题讨论】:

  • i 是最后一个索引时,val[i+1] 在列表之外。
  • 在最后一次迭代中i 会是什么?同时i+1 会是什么?
  • 既然你想让它环绕,请使用(i+1)%len(val)
  • 是的,我刚刚解决了这个问题。那我怎样才能让它变得更好呢?
  • 为什么只有 2 个元素的列表不像 3 个元素的列表那样环绕?

标签: python python-3.x list python-2.7


【解决方案1】:

您可以完全避免索引,方法是使用itertools.combinations() 函数生成每个子列表中所有可能的点配对,如下所示:

from itertools import combinations


l1 = [['a1','a2','a3'], ['b1','b2'], ['c1','a1']]

dicts = [{'start': start, 'end': end}
            for points in l1
                for start, end in combinations(points, 2)]

from pprint import pprint
pprint(dicts, sort_dicts=False)

输出:

[{'start': 'a1', 'end': 'a2'},
 {'start': 'a1', 'end': 'a3'},
 {'start': 'a2', 'end': 'a3'},
 {'start': 'b1', 'end': 'b2'},
 {'start': 'c1', 'end': 'a1'}]

【讨论】:

  • 如果列表中有 5 或 4 个元素,则不起作用。例如,如果列表中有类似 [a1,a2,a3,a4,a5] 的列表。输出我得到的是 [{a1,a2},{a2,a3},{a3,a4},{a4,a5},{a5,a1}] 但我还需要其他连接,例如 [{a1,a3},{ a1,a4},{a2,a5},{a2,a5},{a3,a5}]。这些值丢失了@martineau。我需要将所有值配对
  • Sam:哦,好的,现在我明白你想要什么了——查看更新后的答案。
【解决方案2】:

两个问题:

  1. val[i+1] 不会回到开头,请使用 val[(i+1) % len(val)]
  2. 您每次都覆盖同一个字典,而不是附加到字典列表中。
result = []
for val in list_edges:
    for i, start in enumerate(val, 1):
        result.append({"start": start, "end": val[i % len(val)]})

我没有循环遍历范围,而是使用enumerate() 来获取索引以及列表元素,并指定1 的起始索引以自动添加1。

这不会产生与您显示的完全相同的结果。它还将{"start": "b2", "end": "b1"}{"start": "a1", "end": "c1"} 放入结果列表中,因为它将所有列表都包装回开头。如果 2 元素列表应该被区别对待,你可以在代码中添加一个特殊的检查。

【讨论】:

  • 如果列表中有 5 或 4 个元素,则不起作用。例如,如果列表中有类似 [a1,a2,a3,a4,a5] 的列表。输出我得到的是 [{a1,a2},{a2,a3},{a3,a4},{a4,a5},{a5,a1}] 但我还需要其他连接,例如 [{a1,a3},{ a1,a4},{a2,a5},{a2,a5},{a3,a5}]。这些值缺失
  • 您的代码只是将ii+1 配对。问题在哪里说您需要所有组合?
  • 尝试使用itertools.combinations()
  • 您能否编辑代码以获得建议的解决方案? @Barmar
  • 我回答了你写的问题。这听起来像是一个不同的问题。我给你指出了你需要的工具,试着自己解决它,如果你不能让它工作,我会帮忙。
【解决方案3】:

你确定这不是 IndentationError 吗? for 循环在list_listedges 之后缩进,这不是正确的语法,无论如何,我会这样做:

# just a function for the for loop in the next function, ignore it, though it is fine if you copy it :)
def weave(val1, val2): # unneeded for use but u can use this in other scripts, too
  if len(val1) != len(val2):
    import sys
    sys.stderr.write("length of value 1 and value 2 are not the same, must be the same\n\n[your OS]: FIX IT OR ELSE SATAN WILL INVITE YOU TO HELL PERSONALLY!!!\n\n(BTW your gf is cheating on you, she is going out with me)\n\n[REPL]: ")
    sys.exit(256)

  w = [] # the returned value
  for i, x in enumerate(val2):
    w += [(val1[i], x)]
  return w

# pay attention to THIS:
def listToDict(LIST, *indexers):
 DICT = {}
 for i, a in weave(LIST, indexers):
  DICT = {**DICT, a: i}
 return DICT

print(weave([1, 3, 7, 5], ["1", "3", "7", "5"]))
print(listToDict([1, 3, 7, 5], "1", "3", "7", "5"))

【讨论】:

  • 这不能回答我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
  • 2020-07-29
相关资源
最近更新 更多