在 2022年9月2日星期五 UTC+2 00:17:23,<[email protected]> 写道:
> On 02Sep2022 07:01, Chris Angelico <[email protected]> wrote:
> >On Fri, 2 Sept 2022 at 06:55, James Tsai <[email protected]> wrote:
> >> No but very often when I have written a neat list/dict/set
> >> comprehension, I find it very necessary
> >> to define local variable(s) to make it more clear and concise. Otherwise I
> >> have to break it down
> >> to several incrementally indented lines of for loops, if statements, and
> >> variable assignments,
> >> which I think look less nice.
> >
> >Well, if it's outgrown a list comp, write it on multiple lines. Like I
> >said, not everything has to be a one-liner.
> True, but a comprehension can be more expressive than a less
> "functional" expression (series of statements).
>
> James, can you provide (a) a real world example where you needed to
> write a series of statements or loops and (b) a corresponding example of
> how you would have preferred to have written that code, possibly
> inventing some syntax or misusing ":=" as if it workeed they way you'd
> like it to work?
>
> Cheers,
> Cameron Simpson <[email protected]>
Yeah, I think list comprehension is particularly useful to construct a deeply
nested list/dict. For example, I am now using Plotly to visualize a cellular
network including several base stations and users. Here is the function I have
written:
def plot_network(area, base_stations, users):
bs_poses = np.array([bs.pos for bs in base_stations])
ue_poses = np.array([ue.pos for ue in users])
fig = px.scatter(x=bs_poses[:, 0], y=bs_poses[:, 1])
fig.add_scatter(x=ue_poses[:, 0], y=ue_poses[:, 1])
fig.update_layout(
xaxis=dict(range=[0, area[0]], nticks=5),
yaxis=dict(range=[0, area[1]], nticks=5),
shapes=[dict(
type="circle",
fillcolor="PaleTurquoise",
x0=x-r, y0=y-r, x1=x+r, y1=y+r,
hovertext=f"({x:.2f}, {y:.2f})",
opacity=0.3
) for bs in base_stations for x, y in [bs.pos]
for r in [bs.cell_radius]],
)
return fig
Simply put, I want to scatter the BSs and users, and additionally I want to
draw a big circle around each BS to represent its cell coverage. I can choose
to write 'x0=bs.pos[0]-bs.cell_radius, y0=...' instead, but it becomes less
concise, and if x, y, or r is the return value of a function instead of a
property, it becomes more computationally expensive to repeat calling the
function as well. I also can create the list of 'shapes' by appending to a
list, like
shapes = []
for bs in base_stations:
x, y = bs.pos
r = bs.cell_radius
shapes.append(dict(...))
fig.update_layout(
xaxis=dict(range=[0, area[0]], nticks=5),
yaxis=dict(range=[0, area[1]], nticks=5),
shapes=shapes
)
But in my opinion this is much less concise. I think it looks better to create
the list within the nested structure. So I totally agree that list
comprehension adds much expressiveness in Python. I only wonder whether it is a
good idea to introduce a specific syntax for local variable assignment in list
comprehensions, instead of using "for r in [bs.cell_radius]".
I am also surprised to know that the assignment operator ":=" in a list
comprehension will assign a variable outside of the scope of the comprehension.
I think it does not make sense since a list comprehension without a ":=" will
never change name bindings outside itself.
--
https://mail.python.org/mailman/listinfo/python-list