带有列表索引分配、dict 索引分配和 dict.get 的 Python 分配怪癖

编程入门 行业动态 更新时间:2024-10-26 06:30:24
本文介绍了带有列表索引分配、dict 索引分配和 dict.get 的 Python 分配怪癖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

在 ruby​​ 2.4 中:

x = ['a']y = {}x[0] = y[x[0]] = y.fetch(x[0], y.length)把 y #=>{"a"=>0}

在 Python 3.5 中:

x = ['a']y = {}x[0] = y[x[0]] = y.get(x[0], len(y))打印(y)#=>{0:0}

为什么会这样?

预计到达时间:

y[x[0]] = x[0] = y.get(x[0], len(y))

产生预期的行为(让我很懊恼.)

解决方案

Ruby 和 Python 是不同的语言,做出不同的选择.在 Python 中,赋值是语句,并从从左到右评估多个赋值目标.Ruby 做出了其他选择;赋值是表达式,因此以相反的顺序求值.

所以在 Ruby 中会发生这种情况:

求值 y.fetch(x[0], y.length),产生 0(key 丢失,y 为空).求y[x[0]] = 0,所以y['a'] = 0.这是一个结果为 0 的表达式.求值 x[0] = 0(0y[x[0]] = 0 赋值表达式的结果).

请注意,在 Ruby 中,赋值是一个表达式.可以嵌套在其他表达式中,赋值表达式的结果就是赋值后目标的值.

在 Python 中会发生这种情况:

求值 y.get(x[0], len(y)),产生 0(key 丢失,y 为空).计算 x[0] = 0.求y[x[0]] = 0,所以y[0] = 0.

来自 Python 赋值语句文档:><块引用>

赋值语句评估表达式列表(记住这可以是单个表达式或逗号分隔的列表,后者产生一个元组)并将单个结果对象从左到右分配给每个目标列表.

所以右边的表达式求值,然后从左到右分配给每个目标.

Python 特意做了赋值语句,因为两者的区别:

如果 a = 42:

如果 a == 42:

太难发现了,即使是故意真的会损害代码的可读性.在 Python 中,可读性很重要.很多.

一般来说,您确实希望避免对名称进行赋值,这些名称随后也用于同一语句中的后续赋值.不要给 x[0] 赋值,然后在同一个赋值中再次使用 x[0],这会非常混乱.

In ruby 2.4:

x = ['a']
y = {}
x[0] = y[x[0]] = y.fetch(x[0], y.length)
puts y #=> {"a"=>0}

In python 3.5:

x = ['a']
y = {}
x[0] = y[x[0]] = y.get(x[0], len(y))
print(y) #=> {0: 0}

Why this?

ETA:

y[x[0]] = x[0] = y.get(x[0], len(y))

produces expected behavior (much to my chagrin.)

解决方案

Ruby and Python are different languages, and make different choices. In Python assignments are statements and evaluates multiple assignment targets from left to right. Ruby made other choices; assignments are expressions and as a result are evaluated in the opposite order.

So in Ruby this happens:

Evaluate y.fetch(x[0], y.length), produces 0 (key is missing, y is empty). Evaluate y[x[0]] = 0, so y['a'] = 0. This is an expression resulting in 0. Evaluate x[0] = 0 (0 being the result of the y[x[0]] = 0 assignment expression).

Note that in Ruby, an assignment is an expression. It can be nested inside other expressions, and the result of the assignment expression is the value of the target after assignment.

In Python this happens instead:

Evaluate y.get(x[0], len(y)), produces 0 (key is missing, y is empty). Evaluate x[0] = 0. Evaluate y[x[0]] = 0, so y[0] = 0.

From the Python assignment statements documentation:

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

So the expression on the right-hand-side is evaluated first, and then assignment takes place to each target from left to right.

Python made assignments statements on purpose, because the difference between:

if a = 42:

and

if a == 42:

is so damn hard to spot, and even if intentional really hurt the readability of code. In Python, readability counts. A lot.

Generally speaking, you really want to avoid making assignments to names that are then also used in subsequent assignments in the same statement. Don't assign to x[0] and then use x[0] again in the same assignment, that's just hugely confusing.

这篇关于带有列表索引分配、dict 索引分配和 dict.get 的 Python 分配怪癖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

更多推荐

[db:关键词]

本文发布于:2023-04-28 07:14:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1169658.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:分配   索引   怪癖   列表   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!