我可以在单个for循环上指定嵌套字典的多个键,而不是使用嵌套的for循环吗?

时间:2019-05-07 20:01:58

标签: python nested-loops

我有一个字典字典,像这样:

d = {names: {IDs: {"constant": value, "some_list": []}}

其中每个名称可能具有多个ID,并且每个ID具有常量值和可变长度列表,其中特定字符串作为键。我的目标是在列表达到给定长度时打印名称和IDS。我知道如何使用嵌套的for循环来做到这一点:

for n in d:
    for i in d[n]:
        num = len(d[n][i]["some_list"])
        if num > 5:
            print "Warning %s %s has %i items" % (n, i, num)

我没有理由不能接受以上所述,它可以工作并且可读。

我很好奇,但是是否有一种方法可以在单个for循环中指定n和i。以下内容由于不同的原因而失败:

for one in d.values().keys():  # fails as list has no attribute keys
for one.keys() in d.values():  # fails as functions can't be assigned to calls

以下内容将生成一个元组列表,然后可以对其进行迭代,但在理解范围内仍将包含两个for循环,并且需要在新列表中进行其他循环才能打印:

new_list = [(n, i) for n in d for i in d[n] if len(d[n][i]["some_list"] > 5] 

不使用2个for循环是否不可能?还是我想念的一招?

2 个答案:

答案 0 :(得分:1)

使用2级以上的字典,无论它们是隐藏在函数内部还是明确表示,您总会在某个地方有嵌套循环。

您可能想做的就是更改字典的结构,使其使用多部分键(在元组中):

tupleDict = { (name,idx):content for name,idd in d.items() for idx,content in idd() }

print(tupleDict)

# {('name1', 'ID11'): {'constant': 1, 'some_list': [1]}, ('name1', 'ID12'): {'constant': 2, 'some_list': [2]}, ...}

然后,您可以使用该备用结构应用没有嵌套循环的过滤器:

min5Lists = { k:v for k,v in tupleDict.items() if len(v['some_list'])>5 }

答案 1 :(得分:0)

这里有很多问题。首先,您的语法不正确。

d = {names: {IDs: {"constant": value, "some_list": []}} 

应该更像

d = {"names": {"IDs": {"constant": "some_value", "some_list": []}}}

如果每个名称可以有多个ID,并且可以有多个名称,请显示更完整的示例:

d = {
   "name1": {
      "id1": {"constant": "value1", "some_list": []},
      "id2": {"constant": "value2", "some_list": []},
      },
   "name2": {
      "idA": {"constant": "valueA", "some_list": []},
      "idB": {"constant": "valueB", "some_list": []},
      },
}

由于您在任意一组名称中都有任意一组ID,所以我不认为可以通过一个循环来完成它。

如果您可以在一个循环中完成此操作,将很难理解和维护。