It's not bad per se (assuming you never need to refer to the widgets later) but I personally think it's best to always use variables. In my experience, the layout of a group of widgets will change more than the creation of the widget itself as the app evolves. I think it's smart to group widget creation together, and then group layout commands together. It makes the layout much easier to visualize from the code, and makes debugging the layout much easier.
Plus, of course, if you need to access the variables later then you must use a variable.
So, while it doesn't matter at all with a single widget, it can matter a lot when you have multiple widgets. Given that you must use a variable some of the time, I think it's best to be consistent and use variables all of the time.
For example, consider this code:
label1 = tk.Label(root, text="First Name:")
label2 = tk.Label(root, text="Last Name:")
entry1 = tk.Entry(root)
entry2 = tk.Entry(root)
label1.grid(row=0, column=0, sticky="e")
entry1.grid(row=0, column=1, sticky="ew")
label2.grid(row=1, column=0, sticky="e")
entry2.grid(row=1, column=1, sticky="ew")
I personally find the above to be much more readable than either of the following two examples.
Calling grid
inline:
tk.Label(root, text="First Name:").grid(row=0, column=0, sticky="e")
tk.Label(root, text="Last Name:").grid(row=1, column=0, sticky="e")
tk.Entry(root).grid(row=0, column=1, sticky="ew")
tk.Entry(root).grid(row=1, column=1, sticky="ew")
Calling grid
interleaved with widget creation:
label1 = tk.Label(root, text="First Name:")
label1.grid(row=0, column=0, sticky="e")
label2 = tk.Label(root, text="Last Name:")
label2.grid(row=1, column=0, sticky="e")
entry1 = tk.Entry(root)
entry1.grid(row=0, column=1, sticky="ew")
entry2 = tk.Entry(root)
entry2.grid(row=1, column=1, sticky="ew")