我如何改进 python 中的数据结构?
How can i improve this data like structure in python?
这是我在 python 中为学生创建的类似数据库的结构,我想知道你们是否可以看看这段代码并就如何更好地编写好的代码给我一些建议(意思是看起来不错而且很容易理解,我大约 2-3 周前才开始编码)你们建议的任何事情我都会考虑,我只是想改进 :)
#Our Gui TOOls
from tkinter import *
from tkinter import ttk
#Window
root = Tk()
#Not allowing the window to be resized
root.resizable(height = False , width = False)
#title of window when we get more things in the window
root.title(string = 'Ronald')
#The object /class
class Students:
def __init__(self, root):
self.root = root
self.data = [{"Student Info": "Ronald Colyar", "Gpa": "4.0", "GradeLVL": "10", "NumOfClasses": "6" , 'Parents number': '773-567-2791'},
{"Student Info": "Beta", "Gpa": "1", "GradeLVL": "5", "NumOfClasses": "9", 'Parents number': '773-867-2791'},
{"Student Info": "Charlie", "Gpa": "2", "GradeLVL": "6", "NumOfClasses": "6", 'Parents number': '773-566-2791'}
]
#Container (very vaguly speaking )
self.var = StringVar()
#track what is being put inside entry
self.var.trace("w", self.callback)
#The entry across 2 columns in row 0
self.entry = ttk.Entry(self.root, textvariable=self.var)
self.entry.grid(row=0, column=0, columnspan=2)
#All of the labels that correspond the the information in self.data
self.labels = [(ttk.Label(self.root, text="Student Info"),ttk.Label(self.root)),(ttk.Label(self.root, text="Gpa"),ttk.Label(self.root)),(ttk.Label(self.root, text="GradeLVL"),ttk.Label(self.root)),(ttk.Label(self.root, text="NumOfClasses"),ttk.Label(self.root)),(ttk.Label(self.root, text="Parents number"),ttk.Label(self.root))]
#spacing the labels out in the window by the amount of them
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
#if the entry matches the data , display the data.
def callback(self, *args):
for i in self.data:
#if the data matches evaluates to true
if i["Student Info"] == self.var.get():
#execute if data matches
for c in self.labels:
c[1].configure(text=i[c[0].cget("text")])
#Calling our object inside of root
Students(root)
#Constant loop of our window
root.mainloop()
编程第 3 周你们认为我的学习如何,我是否落后了 3 周,或者我是否有望成为一名优秀的软件开发人员,我也是 16 岁,所以我有几年的时间来掌握这些技能.
就可读性和 Pythonic 最佳实践而言,这段代码布局合理 ()。
可以进行一些主观改进。
其中第一个是这里使用enumerate()
:
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
我们可以使用类似下面的东西代替上面的东西:
for c, i in enumerate(self.labels, 1):
i[0].grid(row = c+1, column=0)
i[1].grid(row = c+1, column=1)
enumerate()
接受一个列表和 returns 一个元组,其索引号与列表中的值相关联,所以在这种情况下,我们声明第一个索引值应该是 1
我们得到一个数据结构 returned 如下所示:
[(1, (ttk.Label(self.root, text="Student Info"),ttk.Label(self.root))),(2, (ttk.Label(self.root, text="Gpa"),ttk.Label(self.root))), . . . ]
这意味着我们可以放弃使用单独的计数变量以及由此产生的混乱。
我们还可以实现一个系统,在该系统中我们可以通过搜索获得 "autocomplete" 功能,我们可以通过修改以下行来实现:
if i["Student Info"] == self.var.get():
收件人:
if i["Student Info"][:len(self.var.get())] == self.var.get() and ([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这看起来很可怕,好像发生了很多事情,但让我们仔细看看。
我们使用字符串拼接,将name字符串的第一部分拉回至Entry
字段中字符串的长度,并与Entry
中的值进行比较,看是否我们得到一个匹配,如果我们这样做,那么程序必须评估是否有任何其他记录可以匹配这个(例如,如果我们注册了 Ron
和 Ronald
我们不希望它自动完成,直到我们确定用户想要 Ron
或 Ronald
)。为此,我们在 if
语句中使用 or
子句:
([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这意味着如果两个条件中的任何一个 return True
我们将继续执行语句下面的代码块。 or
语句的前半部分使用列表理解来 return 名称字符串列表,直到 Entry
中的值的长度,然后计算其中有多少匹配该值在 Entry
中(例如,如果我们有 Ron
和 Ronald
并输入 "Ro"
这将是 return 2
)然后检查查看该计数是否等于 1
。如果是,那么我们 return True
因为我们的数据中不可能有任何其他匹配项。下半部分检查 Entry
中的值是否与我们数据中的任何内容完全匹配,如果我们不这样做,那么 Ron
将永远不会被 returned,因为我们同时拥有 [=21] =] 和 Ronald
因为 Ron
将始终 return 前一个语句的计数 2
。
最后,如果您愿意,可以将数据移动到另一个文件中,例如 .json
或 .csv
(主观上说 .json
文件比 .csv
) 这样它就不会弄乱你的程序。然后您需要导入要在您的程序中使用的数据。这在SO上已经解释了很多,所以你应该能够找到一个对你有帮助的问题。
这是我在 python 中为学生创建的类似数据库的结构,我想知道你们是否可以看看这段代码并就如何更好地编写好的代码给我一些建议(意思是看起来不错而且很容易理解,我大约 2-3 周前才开始编码)你们建议的任何事情我都会考虑,我只是想改进 :)
#Our Gui TOOls
from tkinter import *
from tkinter import ttk
#Window
root = Tk()
#Not allowing the window to be resized
root.resizable(height = False , width = False)
#title of window when we get more things in the window
root.title(string = 'Ronald')
#The object /class
class Students:
def __init__(self, root):
self.root = root
self.data = [{"Student Info": "Ronald Colyar", "Gpa": "4.0", "GradeLVL": "10", "NumOfClasses": "6" , 'Parents number': '773-567-2791'},
{"Student Info": "Beta", "Gpa": "1", "GradeLVL": "5", "NumOfClasses": "9", 'Parents number': '773-867-2791'},
{"Student Info": "Charlie", "Gpa": "2", "GradeLVL": "6", "NumOfClasses": "6", 'Parents number': '773-566-2791'}
]
#Container (very vaguly speaking )
self.var = StringVar()
#track what is being put inside entry
self.var.trace("w", self.callback)
#The entry across 2 columns in row 0
self.entry = ttk.Entry(self.root, textvariable=self.var)
self.entry.grid(row=0, column=0, columnspan=2)
#All of the labels that correspond the the information in self.data
self.labels = [(ttk.Label(self.root, text="Student Info"),ttk.Label(self.root)),(ttk.Label(self.root, text="Gpa"),ttk.Label(self.root)),(ttk.Label(self.root, text="GradeLVL"),ttk.Label(self.root)),(ttk.Label(self.root, text="NumOfClasses"),ttk.Label(self.root)),(ttk.Label(self.root, text="Parents number"),ttk.Label(self.root))]
#spacing the labels out in the window by the amount of them
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
#if the entry matches the data , display the data.
def callback(self, *args):
for i in self.data:
#if the data matches evaluates to true
if i["Student Info"] == self.var.get():
#execute if data matches
for c in self.labels:
c[1].configure(text=i[c[0].cget("text")])
#Calling our object inside of root
Students(root)
#Constant loop of our window
root.mainloop()
编程第 3 周你们认为我的学习如何,我是否落后了 3 周,或者我是否有望成为一名优秀的软件开发人员,我也是 16 岁,所以我有几年的时间来掌握这些技能.
就可读性和 Pythonic 最佳实践而言,这段代码布局合理 (
可以进行一些主观改进。
其中第一个是这里使用enumerate()
:
for i in range(len(self.labels)):
self.labels[i][0].grid(row = i+1, column=0)
self.labels[i][1].grid(row = i+1, column=1)
我们可以使用类似下面的东西代替上面的东西:
for c, i in enumerate(self.labels, 1):
i[0].grid(row = c+1, column=0)
i[1].grid(row = c+1, column=1)
enumerate()
接受一个列表和 returns 一个元组,其索引号与列表中的值相关联,所以在这种情况下,我们声明第一个索引值应该是 1
我们得到一个数据结构 returned 如下所示:
[(1, (ttk.Label(self.root, text="Student Info"),ttk.Label(self.root))),(2, (ttk.Label(self.root, text="Gpa"),ttk.Label(self.root))), . . . ]
这意味着我们可以放弃使用单独的计数变量以及由此产生的混乱。
我们还可以实现一个系统,在该系统中我们可以通过搜索获得 "autocomplete" 功能,我们可以通过修改以下行来实现:
if i["Student Info"] == self.var.get():
收件人:
if i["Student Info"][:len(self.var.get())] == self.var.get() and ([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这看起来很可怕,好像发生了很多事情,但让我们仔细看看。
我们使用字符串拼接,将name字符串的第一部分拉回至Entry
字段中字符串的长度,并与Entry
中的值进行比较,看是否我们得到一个匹配,如果我们这样做,那么程序必须评估是否有任何其他记录可以匹配这个(例如,如果我们注册了 Ron
和 Ronald
我们不希望它自动完成,直到我们确定用户想要 Ron
或 Ronald
)。为此,我们在 if
语句中使用 or
子句:
([x["Student Info"][:len(self.var.get())] for x in self.data].count(self.var.get()) == 1 or i["Student Info"] == self.var.get()):
这意味着如果两个条件中的任何一个 return True
我们将继续执行语句下面的代码块。 or
语句的前半部分使用列表理解来 return 名称字符串列表,直到 Entry
中的值的长度,然后计算其中有多少匹配该值在 Entry
中(例如,如果我们有 Ron
和 Ronald
并输入 "Ro"
这将是 return 2
)然后检查查看该计数是否等于 1
。如果是,那么我们 return True
因为我们的数据中不可能有任何其他匹配项。下半部分检查 Entry
中的值是否与我们数据中的任何内容完全匹配,如果我们不这样做,那么 Ron
将永远不会被 returned,因为我们同时拥有 [=21] =] 和 Ronald
因为 Ron
将始终 return 前一个语句的计数 2
。
最后,如果您愿意,可以将数据移动到另一个文件中,例如 .json
或 .csv
(主观上说 .json
文件比 .csv
) 这样它就不会弄乱你的程序。然后您需要导入要在您的程序中使用的数据。这在SO上已经解释了很多,所以你应该能够找到一个对你有帮助的问题。