将字典键、值与嵌套列表元素进行比较 - Python

Compare dictionary key, values with nested list elements - Python

尝试将字典中的键、值与嵌套列表元素匹配

dict = {'a':[1, 5], 'c':[7, 9], 'f':[10, 12], 'b':[15, 20]}
list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]
list_A_no_reps =['a', 'b', 'c', 'd', 'f']

我正在尝试获取一个列表,该列表的值与 list_A 和 dict 匹配,即列表 a 的值(嵌套列表中的第二个元素)应该位于值列表对之间的字典。

match_list = [['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]

我试图首先将 dict 的键与 list_A_no_reps 匹配,如果匹配,我试图找出它是否位于每个键、值对的值之间。到目前为止我有这个:

g = []
for key, values in dict.items():
   for element in list_A_no_rep:
      if key == element:
         for cord in list_A:
            if (values[0] <= int(cord[1]) <= values[2]):
               g.append(cord)

更新

values[2]更改为values[1]

由于您的字典有两个元素并且索引是从零开始的,因此 [1, 5] 将导致 values[0] == 1 and values[1] == 5

您可能还想寻求更好的解决方案,通过省略 list_A_no_reps 并删除 if key == element 块,然后使用 cord[0] 进行比较。

我会将字典中的子列表按第一个元素(字母)进行分组,然后遍历您的原始字典并检查每个键是否在分组字典中并进行比较。

d = {'a': [1, 5], 'c': [7, 9], 'f': [10, 12], 'b': [15, 20]}

list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]

from collections import defaultdict

d2 = defaultdict(list)

for k,v in list_A:
    d2[k].append(v)

out = []
for k, v in d.items():
    if k in d2:
        vals = d2[k]
        for v2 in vals:
            if v[0] <= int(v2) <= v[1]:
                out.append([k,v2])
print(out)
['a', '4'], ['c', '7'], ['b', '17'], ['f', '11'], ['f', '12']]

或者使用viewkeys获取常用键:

out = []
for k in d.viewkeys() & d2.viewkeys():
    vals, v = d2[k], d[k]
    for v2 in vals:
        if v[0] <= int(v2) <= v[1]:
            out.append([k,v2])

或者只是循环 listA:

d = {'a': [1, 5], 'c': [7, 9], 'f': [10, 12], 'b': [15, 20]}

list_A = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]

out = []
for sub in list_A:
    k, val = sub
    if k in d:
        v = d[k]
        if v[0] <= int(val) <= v[1]:
            out.append(sub)
print(out)
[['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]

你可以试试:

g = []
for key, values in dict.items():
    if key in list_A_no_rep:
        for cord in list_A:
        if ( cord[0] == key ):
                if (values[0] <= int(cord[1]) <= values[1]):
                    g.append(cord)
print g

输出:

[['a', '4'], ['c', '7'], ['b', '17'], ['f', '11'], ['f', '12']]

您的代码修改:

g = []
for key, values in dict.items():
    for element in list_A_no_rep:
        if key == element:
            for cord in list_A:
                if ( cord[0] == element ): #line added
                    if (values[0] <= int(cord[1]) <= values[1]):
                        g.append(cord)

您的代码中的问题是您也在检查 list_A 的所有其他元素。因此,您会得到可能在另一个键范围内的不需要的值。因此需要一个 if 条件来检查是否发生了与相同键的有效比较。

例如,如果没有 if 条件,您会用 c:[7,9] 检查 ['a','7']。因此,即使它不满足为 a.

指定的范围,您也会将其包含在 g
d = {'a':[1, 5], 'c':[7, 9], 'f':[10, 12], 'b':[15, 20]}
li = [['a', '4'], ['a', '7'], ['b', '17'], ['b', 10], ['c', '7'], ['d', '7'], ['f', '11'], ['f', '12']]

li 中的每组值查找 d 中的键比为 d 中的每个键遍历列表更快。这可以用 list comprehension:

在一行中完成
match_li = [v for v in li if v[0] in d and  d[v[0]][0] <= int(v[1]) <=  d[v[0]][2]]

产量

[['a', '4'], ['b', '17'], ['c', '7'], ['f', '11'], ['f', '12']]