亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在具有匹配屬性的 dict 數組中查找最小值,返回最大的分組

在具有匹配屬性的 dict 數組中查找最小值,返回最大的分組

大話西游666 2021-08-14 16:43:03
這很容易通過幾個循環來做到這一點,但我相信有一種更有效的方法來實現這一點,我很想學習。考慮以下 dict 數組,它表示從 nosql 數據庫中提取的數據。x = [    {        "loc" : "alpha",        "tag" : 1,        "dist" : 5    },    {        "loc" : "bravo",        "tag" : 0,        "dist" : 2    },    {        "loc" : "charlie",        "tag" : 5,        "dist" : 50    },    {        "loc" : "delta",        "tag" : 4,        "dist" : 2    },    {        "loc" : "echo",        "tag" : 2,        "dist" : 30    },    {        "loc" : "foxtrot",        "tag" : 4,        "dist" : 2    },    {        "loc" : "gamma",        "tag" : 4,        "dist" : 2    },    {        "loc" : "hotel",        "tag" : 0,        "dist" : 2    },]我想找到所有具有最低 'dist' 值的項目,并且如果有多個具有相同最低值的 dict,我希望對具有相同最低值的 dict 最多的屬性 'tag' 進行分組.例如,上面所需的返回數據是:r = [    {        "LocationName" : "delta",        "tag" : 4,        "dist" : 2    },    {        "loc" : "foxtrot",        "tag" : 4,        "dist" : 2    },    {        "loc" : "gamma",        "tag" : 4,        "dist" : 2    }]總結:dist:2 是最低值,[bravo, delta, foxtrot, gamma, hotel] 的dist 都是2,[bravo, hotel] 的標簽是:0,[delta, foxtrot, gamma] 的標簽都是的:4。返回一個 dicts [delta, foxtrot, gamma] 數組,因為它們有更多具有相同匹配標簽和最低 dist 的。我正在使用 python 3.6。
查看完整描述

2 回答

?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

您可以key為max()和指定一個(即 lambda 函數),min()這可以幫助解決此問題。對于你的第一次測試,


lowest_single_dist = min(x, key=lambda i: i["dist"])

返回 中x具有最低值的元素"dist"。如果您想要所有具有該標簽值的元素,您可以使用列表理解:


lowest_dists = [i for i in x if i["dist"] == lowest_single_dist["dist"]]

為了獲得最大的分組,我將首先"tag"在該子集中創建一組可能的值,然后檢查每個有多少個lowest_dists,然后取哪個計數最高:


tags = [i["tag"] for i in lowest_dists]              # get a list of just the tags

ct = {t: tags.count(t) for t in set(tags)}           # make a dict of tag:count for each unique tag

max_tag = max(ct, key=lambda x: ct[x])               # find the largest count and get the largest tag

r = [i for i in lowest_dists if i["tag"] == max_tag] # use another list comprehension to get all the max tags

如果你想把它全部縮短成兩行,你可以不那么pythonic并這樣做:


m = min(x, key=lambda i: (i["dist"], -1 * max([j["tag"] for j in x if j["dist"] == i["dist"]].count(i["tag"])))

r = [i for i in x if i["tag"] == m["tag"] and i["dist"] == m["dist"]]

這利用了這樣一個事實,即您可以返回一個元組作為排序的鍵,并且只有在第一個值相等時才會檢查元組的第二個值。我將稍微擴展第一行并解釋每個部分的作用:


m = min(x, key=lambda i: (

    i["dist"], -1 * max(

        [j["tag"] for j in x if j["dist"] == i["dist"]].count(i["tag"])

    ))

  • 最內層的列表推導式為所有元素生成一個標簽列表,其x值為"dist"asi

  • 然后,取與相同的標簽計數 i

  • 乘以 -1 使其為負數,以便min()正確運行

  • 創建一個i["dist"]和我們剛剛計算的值(i["tag"]in的頻率x)的元組,并為每個元素返回該值

  • 分配給m列表中具有最低值"dist"和最頻繁值的元素"tag"

  • 分配給具有相同值r的元素的子列表和x"dist""tag"

所以基本上與上面相同的過程,但更短,效率更低,并且更復雜一些。


查看完整回答
反對 回復 2021-08-14
?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

按“dist”中的值對字典列表進行排序,并取最低值


x.sort(key= lambda x:x['dist'])

lowest = x[0]['dist']

創建一個字典列表,其中 'dist' 的值等于最低值


x2 = [i for i in x if i['dist']==lowest]

這應該是你的答案。如果列表中有多個項目,請重復上述過程。


if len(x2)>1:

  x3 = [i['tag'] for i in x2]

  mode = max(set(x3), key=x3.count)

  r = [i for i in x if i['tag']==mode]


查看完整回答
反對 回復 2021-08-14
  • 2 回答
  • 0 關注
  • 157 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號