我有一本以字典为值的字典。以下是我的字典的结构
myD = {'key1': {'x' : 123, 'y' : 432},
'key2': {'x' : 456, 'y' : 565},
'key3': {'x' : 789, 'y' : 420},
...}
我需要比较该字典的值(如您所见,我在每个值中都有类似的字典结构)并生成以下输出。策略将遍历值字段中的每个词典,并为给定键选择最小值,然后将其插入新词典中。例如,如果我们考虑值字典中的x键,它的最小值为123
。因此,我的新词典应具有x:123
。
my_newD = {'x' : 123, 'y' : 420, ...}
我可以使用3个for循环来实现这一点,但是有什么优雅的方法可以减少for循环吗?
答案 0 :(得分:4)
我想出了两个循环:
my_newD = {key: min(item[key] for item in myD.values())
for key in next(iter(myD.values()))}
编辑:按照@Andriy Makukha的建议,删除了对外部循环中'key1'
的明确依赖
编辑2:将myD[list(myD.keys())[0]]
替换为next(iter(myD.values()))
。
不知道哪一个隐秘性较低,但使用next
和iter
确实看起来更有效。
感谢Leo K指出这一点!
答案 1 :(得分:4)
以下是使用button.disableProperty().bind(Bindings.size(tableView.getSelectionModel().getSelectedIndices())
.isNotEqualTo(1));
的O(n)解决方案:
collections.defaultdict
答案 2 :(得分:1)
两个循环:
myD = {'key1': {'x' : 123, 'y' : 432},
'key2': {'x' : 456, 'y' : 565},
'key3': {'x' : 789, 'y' : 420}}
resD = {}
for key in myD:
subD = myD[key]
for k in subD:
resD[k] = min(resD[k], subD[k]) if k in resD else subD[k]
print (resD)
输出:
{'x': 123, 'y': 420}
答案 3 :(得分:1)
使用pandas
的另一种可能性(在优雅方面更好):
import pandas as pd
my_newD = pd.DataFrame(myD).min(axis=1).to_dict()
答案 4 :(得分:1)
这是我在O(n)中的解决方案
>>> from itertools import accumulate
>>> min_t = lambda *t: [min(r) for r in zip(*t)]
>>> *_, min_vals = accumulate([v.values() for k,v in myD.items()], min_t)
>>> keys = next(iter(myD.values())).keys()
>>> dict(zip(keys, vals))
{'x': 123, 'y': 420}
>>>
说明
>>> from itertools import accumulate
>>>
>>> myD = {'key1': {'x': 123, 'y': 432}, 'key2': {'x': 456, 'y': 565}, 'key3': {'x': 789, 'y': 420}}
>>>
>>> # Define a func to find min of tuples
>>> def min_t(*t):
... return [min(r) for r in zip(*t)]
...
>>> # Build the tuple
>>> t = (v.values() for k,v in myD.items())
>>> *_, min_vals = accumulate(t, min_t)
>>> min_vals
[123, 420]
>>>
>>> keys = next(iter(myD.values())).keys()
>>> keys
dict_keys(['x', 'y'])
>>>
>>>
>>> dict(zip(keys, vals))
{'x': 123, 'y': 420}
>>>
或采用单行
>>> from itertools import accumulate
>>> from collections import deque
>>> dict(zip(next(iter(myD.values())).keys(), deque(accumulate((v.values() for k,v in myD.items()), lambda *t: [min(r) for r in zip(*t)]), maxlen=1).pop()))
{'x': 123, 'y': 420}
答案 5 :(得分:0)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="panel panel-warning">
<div class="panel-heading">
<span class="h4">Day - 1</span> |
<span class="secTitle"><input name="sec[title]" value="Day 1" type="text"></span>
<span class="pull-right panel-menu" data-secid="11">
<a href="#" class="btn btn-primary btn-sm sec-form-btn">Save changes</a>
<span class="fa fa-refresh fa-spin fa-1x fa-fw edit-sec-loader hidden"></span>
</span>
</div>
<div class="panel-body">
<div class="secDes mb10">
<textarea name="sec[des]" class="form-control"></textarea>
</div>
</div>
</div>
答案 6 :(得分:0)
此动态代码适用于任意数量的变量。它的复杂度为O(M * N),其中M =要查找最小值的变量数,N = myD
# here, M = 3, N = 3
myD = {'key1': {'x' : 123, 'y' : 432, 'z': 100},
'key2': {'x' : 456, 'y' : 565, 'z': 99},
'key3': {'x' : 789, 'y' : 420, 'z': 250}}
firstKey = "key1"
# assume firstKey has all the minimum entries
# use it as a base to compare all other values to
minD = {}
for (k,v) in myD[firstKey].items():
minD[k] = v
items = myD.items()
# find minimum of variable x, then y, then z
for variable in minD:
print "Finding minimum of " + variable
for key, dictionary in items:
keyVal = dictionary[variable]
if minD[variable] > keyVal:
minD[variable] = keyVal
print minD # {'y': 420, 'x': 123, 'z': 99}