我可以在单个 for 循环上为嵌套字典指定多个键而不是使用嵌套 for 循环吗?
Can I specify multiple keys to nested dictionary on single for loop rather than using nested for 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+ 级字典,您总会在某处有嵌套循环,无论它们是隐藏在函数内部还是显式表达。
您可能想要做的是更改字典的结构,使其使用 multi-part 键(在元组中):
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 }
这里有很多问题。首先,你的语法不正确。
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,我不认为它可以通过一个循环完成。
如果一个循环搞定,理解和维护起来会很困难
我有一个看起来像这样的字典:
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+ 级字典,您总会在某处有嵌套循环,无论它们是隐藏在函数内部还是显式表达。
您可能想要做的是更改字典的结构,使其使用 multi-part 键(在元组中):
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 }
这里有很多问题。首先,你的语法不正确。
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,我不认为它可以通过一个循环完成。
如果一个循环搞定,理解和维护起来会很困难