为了账号安全,请及时绑定邮箱和手机立即绑定

如何从给定的矩阵创建字典

如何从给定的矩阵创建字典

阿波罗的战车 2021-09-14 09:47:45
假设我得到一个类似于电话键盘的矩阵,例如-1 2 34 5 67 8 9  0我如何生成以下字典而不实际输入它(元组不一定要排序)-my_dict = {1: (1, 2, 4, 5), 2: (1, 2, 3, 4, 5, 6), 3: (2, 3, 5, 6),           4: (1, 2, 4, 5, 7, 8), 5: (1, 2, 3, 4, 5, 6, 7, 8, 9),           6: (2, 3, 5, 6, 8, 9), 7: (0, 4, 5, 7, 8),           8: (0, 4, 5, 6, 7, 8, 9), 9: (0, 5, 6, 8, 9),           0: (0, 7, 8, 9)}这本字典基本上告诉我给定数字的所有相邻数字。例如,1 的相邻数字是 1、2、4、5。编辑:理想情况下,矩阵应存储为列表列表:[[1, 2, 3], [4, 5, 6], [7, 8, 9], [None, 0, None]]我知道蛮力方法,但想知道一种有效地做到这一点的方法。
查看完整描述

3 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

假设键盘存储为位置字典(元组 x,y)和相应的数字作为值,您可以执行以下操作:


import itertools



def distance(p1, p2):

    return sum((x1 - x2) ** 2 for x1, x2 in zip(p1, p2))



def neighbors(positions, target):

    return [position for position in positions if distance(target, position) < 4]



def numbers(kpad, keys):

    return tuple(sorted(map(kpad.get, keys)))



values = list(range(1, 10)) + [0]

positions = list(itertools.product([0, 1, 2], repeat=2)) + [(3, 1)]


keypad = dict(zip(positions, values))


result = {value: numbers(keypad, neighbors(keypad, key)) for key, value in keypad.items()}

print(result)

输出


{0: (0, 7, 8, 9), 1: (1, 2, 4, 5), 2: (1, 2, 3, 4, 5, 6), 3: (2, 3, 5, 6), 4: (1, 2, 4, 5, 7, 8), 5: (1, 2, 3, 4, 5, 6, 7, 8, 9), 6: (2, 3, 5, 6, 8, 9), 7: (0, 4, 5, 7, 8), 8: (0, 4, 5, 6, 7, 8, 9), 9: (0, 5, 6, 8, 9)}

这个想法是为每个位置获取相邻点的值。


更新


要将列表 a 转换为键盘字典,您可以执行以下操作:


data = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [None, 0, None]]

keypad = {(i, j): value for i, sub in enumerate(data) for j, value in enumerate(sub) if value is not None}

其余方法保持不变。


查看完整回答
反对 回复 2021-09-14
?
杨魅力

TA贡献1811条经验 获得超6个赞

您可以使用生成器函数:


import re

def all_adjacent(_c, _graph):

   _funcs = [lambda x,y:(x+1, y), lambda x,y:(x+1, y+1), lambda x,y:(x+1, y-1), lambda x,y:(x, y+1), lambda x,y:(x-1, y+1), lambda x,y:(x-1, y-1), lambda x,y:(x, y-1), lambda x,y:(x-1, y)]

   yield _graph[_c[0]][_c[1]]

   for func in _funcs:

     a, b = func(*_c)

     try:

       if a >= 0 and b >= 0:

         _val = _graph[a][b]

         if _val != '  ':

           yield _val

     except:

       pass



s = """

1 2 3

4 5 6

7 8 9

  0  

"""

new_data = [re.findall('\d+|\s{2,}', i) for i in filter(None, s.split('\n'))]

final_results = {c:list(all_adjacent((i, d), new_data)) for i, a in enumerate(new_data) for d, c in enumerate(a) if c != '  '}

_result = {int(a):tuple(sorted(map(int, b))) for a, b in final_results.items()}

输出:


{1: (1, 2, 4, 5), 2: (1, 2, 3, 4, 5, 6), 3: (2, 3, 5, 6), 4: (1, 2, 4, 5, 7, 8), 5: (1, 2, 3, 4, 5, 6, 7, 8, 9), 6: (2, 3, 5, 6, 8, 9), 7: (0, 4, 5, 7, 8), 8: (0, 4, 5, 6, 7, 8, 9), 9: (0, 5, 6, 8, 9), 0: (0, 7, 8, 9)}

编辑:将矩阵存储为列表列表:


import re

def all_adjacent(_c, _graph):

  _funcs = [lambda x,y:(x+1, y), lambda x,y:(x+1, y+1), lambda x,y:(x+1, y-1), lambda x,y:(x, y+1), lambda x,y:(x-1, y+1), lambda x,y:(x-1, y-1), lambda x,y:(x, y-1), lambda x,y:(x-1, y)]

  yield _graph[_c[0]][_c[1]]

  for func in _funcs:

    a, b = func(*_c)

    try:

      if a >= 0 and b >= 0:

        _val = _graph[a][b]

        if _val is not None:

          yield _val

    except:

      pass


new_data = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [None, 0, None]]

final_results = {c:(i, d) for i, a in enumerate(new_data) for d, c in enumerate(a) if c is not None}

_result = {int(a):tuple(map(int, all_adjacent(b, new_data))) for a, b in final_results.items()}

输出:


{1: (1, 4, 5, 2), 2: (2, 5, 6, 4, 3, 1), 3: (3, 6, 5, 2), 4: (4, 7, 8, 5, 2, 1), 5: (5, 8, 9, 7, 6, 3, 1, 4, 2), 6: (6, 9, 8, 2, 5, 3), 7: (7, 0, 8, 5, 4), 8: (8, 0, 9, 6, 4, 7, 5), 9: (9, 0, 5, 8, 6), 0: (0, 9, 7, 8)}


查看完整回答
反对 回复 2021-09-14
?
冉冉说

TA贡献1877条经验 获得超1个赞

假设您的矩阵如下所示:


m = [

    [1, 2, 3],

    [4, 5, 6],

    [7, 8, 9],

    [None, 0, None]

]

您可以蛮力解决您的解决方案,只需遍历矩阵并使用 defaultdict 收集相邻单元格:


from collections import defaultdict

from pprint import pprint


m = [

    [1, 2, 3],

    [4, 5, 6],

    [7, 8, 9],

    [None, 0, None]

]


rows = len(m)

cols = len(m[0])


# adjacent cells

adjacency = [(i, j) for i in (-1, 0, 1) for j in (-1, 0, 1) if not i == j == 0]


d = defaultdict(list)

for r in range(rows):

    for c in range(cols):

        cell = m[r][c]

        if cell is not None:

            d[cell].append(cell)

            for x, y in adjacency:

                if 0 <= r + x < rows and 0 <= c + y < cols:

                    adjacent = m[r + x][c + y]

                    if adjacent is not None:

                        d[cell].append(adjacent)


# print sorted adjacent cells

pprint({k: tuple(sorted(v)) for k, v in d.items()})

这给出了排序的相邻单元格的字典:


{0: (0, 7, 8, 9),

 1: (1, 2, 4, 5),

 2: (1, 2, 3, 4, 5, 6),

 3: (2, 3, 5, 6),

 4: (1, 2, 4, 5, 7, 8),

 5: (1, 2, 3, 4, 5, 6, 7, 8, 9),

 6: (2, 3, 5, 6, 8, 9),

 7: (0, 4, 5, 7, 8),

 8: (0, 4, 5, 6, 7, 8, 9),

 9: (0, 5, 6, 8, 9)}


查看完整回答
反对 回复 2021-09-14
  • 3 回答
  • 0 关注
  • 299 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信