函数适用于命令行,但不适用于脚本

Functions works on command line, but not in script

我在自己的文件 MTG.py 中定义了以下函数。它应该以邻接矩阵作为输入,并创建一个图。

import pygraphviz as pgv
import numpy as np

def matrix_to_graph(M):
    A = pgv.AGraph()
    for i in range(0, np.shape(M)[0]):
        for j in range(0, np.shape(M)[0]):
            if i < j and M[i][j] == 1:
                A.add_edge(i,j)
    A.write('M.dot')
    C = pgv.AGraph('M.dot')
    C.layout()
    C.draw('M.png')

当我从命令行运行

from MTG import matrix_to_graph
M = [[0, 1, 0, 1, 1], [1, 0, 1, 1, 0], [0, 1, 0, 0, 0], [1, 1, 0, 0, 1], [1, 0, 0, 1, 0]]
matrix_to_graph(M)

我得到了我想要的,这是打印到 M.png 的正确图表。

但是,如果我在上面的代码中添加(没有缩进,即在函数定义之外)

M = input("Enter an adjacency matrix:")
matrix_to_graph(M)

我收到错误

 for i in range(0, np.shape(M)[0]):
IndexError: tuple index out of range

我想这是因为输入函数接受了我认为是矩阵,但实际上是其他东西。我试图通过使用 np.matrix(M) 来纠正这个问题,但这会将我的矩阵变成 1x16 向量。我是 Python 的新手,我确信有 1000 种方法可以更好地做到这一点,但我真的很想弄清楚为什么这种特殊方法不起作用。

我正在使用 PyCharm 2017.1.3(社区版,如果重要的话)和 Python 3.6.

Python 3's input returns a str, 它不会解析它来制作一个 Python 数据结构只是因为内容看起来像Python 文字。在这种情况下,如果您希望能够输入 list of list of ints 文字,我建议 using ast.literal_eval 以(安全地)从字符串转换将矩阵文字表示为 list 本身:

import ast

M = ast.literal_eval(input("Enter an adjacency matrix:"))

您可能已经习惯了 Python 2,其中 input 相当于 Python 3 中的 eval(input(...)),但是 input 的那个版本是危险的并且有充分理由被移除; ast.literal_eval 在不允许任意代码执行的情况下为您提供所需的内容。