从字典中的列表中查找元素,然后返回该键

时间:2018-10-20 14:12:13

标签: python python-3.x list dictionary python-2.x

如果我将someDictionary定义为

{'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}

someList定义为

[51, 52, 53, 54, 55, 56]

如何在someDictionary中找到与someList中的元素匹配的键?现在,我假设不会有超过一场比赛。

我认为应该是这样的:

for k, v in someDictionary.items():
    if v == someList:
        myAnswer = k

鉴于上面的代码,myAnswer将是3

我需要做的第二部分是,如果someList不包含someDictionary中的元素,请在someDictionary中查找大于(但最接近)someList {中的最后一个元素的值{1}}

在这种情况下,myAnswer将为someList[-1]

8 个答案:

答案 0 :(得分:3)

听起来您想要bidict

# 5. rasterize vector layer and save as tiff
gdal.UseExceptions()

# a) define resolution and NoData value of new raster
x_res = 0.001 # degree per pixel
y_res = 0.001 # smaller value gives larger tiffs (higher resolution)
NoData_value = -9999

# b) filename for output
_out = r"D:/asdf23.tiff"

# c) get extent of layer
qgsRect = layer.extent()
x_min = qgsRect.xMinimum(); x_max = qgsRect.xMaximum()
y_min = qgsRect.yMinimum(); y_max = qgsRect.yMaximum()

# d) create target - TIFF
nbPixelX = int( (x_max - x_min) / x_res )
nbPixelY = int( (y_max - y_min) / y_res )

srs = layer.sourceCrs()
raster = gdal.GetDriverByName('GTiff').Create(_out, nbPixelX, nbPixelY, 1, gdal.GDT_Int32)
raster.SetProjection(srs.toWkt())
raster.SetGeoTransform((x_min, x_res, 0, y_max, 0, -y_res))
band = raster.GetRasterBand(1)
band.SetNoDataValue(NoData_value)

# e) Rasterize
err = gdal.RasterizeLayer(raster, [1], layer, burn_values=[102])

这允许在任一方向上进行 O(1)查找。现在,您可以遍历>>> from bidict import bidict # pip install bidict >>> d = bidict({'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}) >>> d['3'] 55 >>> d.inv[55] '3' 并检查元素是否有效someList

答案 1 :(得分:2)

第一部分,找到在列表中具有字典值的键的列表。

someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]

res = [key for key, value in someDictionary.items() if value in someList]

第二部分,如果第一部分没有结果,请找到具有最接近的较大值的键(续):

if not res:
    res = min ([(value, key) for key, value in someDictionary.items() if value > max(someList) ])[1]

答案 2 :(得分:1)

myAnswer = ''
closest_to = someList[-1]
closest_diff = 0
for k in someDictionary:
    if someDictionary[k] in someList:
         myAnswer = k
         break; # stop the loop when exact match found
    diff = someDictionary[k] - closest_to
    if diff > 0 and diff < closest_diff:
         closest_diff = diff
         myAnswer = k # this would save key of larger but closest number to last in someList

答案 3 :(得分:1)

首先使用列表推导收集值在lst中的所有键,如果没有匹配项,则过滤值大于lst[-1]的键。根据键值与lst中的最后一项之差的abs值对它们进行排序后,取0索引,最接近的项。

dct = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
lst = [51, 52, 53, 54, 55, 56]

my_answer = [int(i) for i in dct if dct[i] in lst]
if my_answer:
    print(*my_answer) # => 3
else:
    close = [i for i in dct if int(dct[i]) > max(lst)]
    closest = sorted(close, key=lambda x: abs(dct.get(x) - lst[-1]))[0]
    print(closest) # => 6

答案 4 :(得分:1)

  

如何在someDictionary中找到与其中的元素匹配的键   someList

使用字典将键映射到值。在O(1)时间内不可能相反。但是您可以在O( n )时间内进行迭代,直到可以将列表元素与字典值匹配为止。

为此,您可以使用一个简单的for循环,迭代字典或列表。

d = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
L = [51, 52, 53, 54, 55, 56]

def find_key_dict(d, L):
    L_set = set(L)  # convert to set for O(1) lookup
    for k, v in d.items():
        if v in L_set:
            return k

def find_key_list(d, L):
    d_rev = {v: k for k, v in d.items()}  # reverse dict for value -> key map
    for i in L:
        if i in d_rev:
            return d_rev[i]

find_key_dict(d, L)  # '3'
find_key_list(d, L)  # '3'

也可以使用next将这些函数重写为1行生成器表达式,但这不一定会更有效。

  

我需要做的第二部分是,如果someList不包含   someDictionary中的元素,在someDictionary中找到值   大于(但最接近)someList

中的最后一个元素

您可以使用带有for... else...的{​​{1}}结构编写类似的函数:

min

答案 5 :(得分:1)

对于第一个问题,您只是使用错误的运算符来检查值是否在someList

for k, v in someDictionary.items():
    if v in someList:
        myAnswer = k

关于第二个问题,您可以通过这种方式扩展先前的代码

for k, v in someDictionary.items():
     if v in someList:
         myAnswer = k
         break
else:
     myAnswer = None
     for k, v in someDictionary.items():
         if v > someList[-1] and (myAnswer is None or v < someDictionary[myAnswer]):
             myAnswer = k

答案 6 :(得分:1)

如果字典和列表很大,尤其是如果有许多列表要针对同一个字典进行测试,则值得准备数据以便更快地执行。

__init__中最差的操作是排序,即O(n * log(n))。它使我们可以使用bisect在O(log(n))中最后一种情况下找到最接近的值。

from bisect import bisect


class FindInDict:
    def __init__(self, someDictionary):
        self.dict_by_values = {val: key for key, val in someDictionary.items()}
        self.dict_values_set = set(sorted_values)
        self.sorted_values = sorted(someDictionary.values())

    def find(self, someList):
        common = set(someList).intersection(self.dict_values_set)
        if common:
            key = self.dict_by_values[common.pop()]
        else:
            closest_value = self.sorted_values[bisect(self.sorted_values, someList[-1])]
            key = self.dict_by_values[closest_value]
        return key



someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}    
finder = FindInDict(someDictionary)

finder.find([51, 52, 53, 54, 55, 56])
# 3

finder.find([51, 52, 53, 54, 56])  # no common value
# 6

答案 7 :(得分:1)

以下内容可以解决您的问题的两个部分,并且应该易于修改以处理可能弹出的任何讨厌的“边缘情况”:

function somefunc(obj) {
   let temp = {};  
   let tempuserlist = [];
   for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
         if(!obj[key].hasOwnProperty("userlist")) {
            somefunc(obj[key]);
         }
         obj[key].userlist.forEach(function(element) {
            if (!temp.hasOwnProperty(element.name)){
              tempuserlist.push(temp[element.user] = { user: element.user});
              temp[element.user].resultlist = [];
              temp[element.user].val= 0;
            } temp[element.name].resultlist.push(element.val);
         });
         for (const user in tempuserlist) {
              tempuserlist[user].val= Math.round(tempuserlist[user].val/ tempuserlist[user].resultlist.length);
         }
      }
   }
   obj.userlist = tempuserlist;
}