python两个数组画图_Python关于数据比较的小问题

有人问了这么个问题:有一系列恒星光谱,希望选出其中特定的两个光谱型的数据来画图,但是一直失败。我看了下,代码大概是这样的:(在原代码基础上简化了一下)

id_ok = []

n = len(dat_all)

for i in range(n):

  if dat_all[i]["objtype"] == ("IV" or "III"):

    id_ok.append(i)

n_ok = len(id_ok)

for j in range(n_ok):

  # 这里省略画图步骤

  plot(dat_all[id_ok[j]])

然后,只画出了第一类恒星(IV)的图,如果交换两者,还是只能画写在前面的那一种。

先解析一下原作者的设计意图:他希望能够判断第i个记录的objtype字段,如果是"IV"或者"III"则添加到列表中,记录下来,后面对添加后的列表进行画图。

估计很多人脑中已经有这个问题的十八种解决办法了……那么你可以拉到底,点一下广告和“在看”然后退出了,下面的内容不是针对你的。

首先解读一下上面那一段代码是怎么被python执行的。if那一句可以简化成:

if x == (a or b):

这句话从Python的语法来说,是先对(a or b)进行求值,然后和x进行==比较。

很多人觉得or作为一个逻辑运算符,前后应该是两个bool表达式。而实际上python的理解是,需要一个bool值的时候,如果你给了一个别的类型,那么非零非空的值就被理解成True,而0/0.0/""/[]/()/{}/None这样的,则被当做是False。此外,尽管其他类型表达式被当做bool使用,但是表达式本身还是原始值,不会被强行改为True/False。

其次,and/or是典型的短路运算符,意思就是当左值可以决定运算结果时,右值直接被忽略,表达式不会被求值,如果右侧表达式中有对变量的赋值,或者输出,都不会发生,因为彻底不执行。一旦发现and左边是False,或者or左边是True,整个运算直接返回左值,不再执行。

注意:这里是说的返回左值本身,而不是返回True/False!

也就是说,表达式 a or b,如果a不是False,或者上面说的可以当做False的其他值,那么就会返回a,否则返回b,实际上根本不检查b是T还是F还是别的啥,直接求值并返回。

a or b 可以当做是这么一个if表达式:a if a else b

然后,才是这个表达式和前面的x去判断是否相等。显然的,在前面的例子中,右侧的b彻底被忽略了,所以不管怎么调整顺序,肯定显示前者。

那么该怎么改呢?因为问的时候我正好在买菜……等我买完,对方已经自己解决了:

for i in range(n):

  if dat_all[i]["objtype"] == "IV":

    id_ok.append(i)

  if dat_all[i]["objtype"] == "III":

    id_ok.append(i)

嗯,解决方法不是最优的,但是也是解决了问题的。那么下面说说怎么做比较“高档”。

1,使用or连接多个条件

for i in range(n):

  if dat_all[i]["objtype"] == "IV" or dat_all[i]["objtype"] == "III":

    id_ok.append(i)

应该说,这才是or在这里的正确用法。

2,使用in运算符和list/tuple

for i in range(n):

  if dat_all[i]["objtype"] in ("IV", "III"):

    id_ok.append(i)

虽然看起来和之前有点像,但是这里用in运算符,实际上in执行的也是==操作。

显然的,这里用["IV", "III"]也可以,一样的。反正都是一次性使用。

3,数组运算

由于这实际上做的是从数组中选出目标的操作,所以可以直接用where:

id_ok = np.where(

  (dat_all["objtype"] == "IV") |

  (dat_all["objtype"] == "III") )

不过这里就稍微复杂一些了,这个|运算是咋回事?为啥要这么加括号?

首先说明一下,由于and/or这两个逻辑运算符,没法和数组结合,所以得用&和|运算符。前面一个条件是对整个数组做的,得到的是一个bool数组,后面也是。但是&|是位运算符,所以实际上反而是把True/False当做1/0来处理的,

至于括号呢,因为&|的运算符优先级比==高,所以得加上括号。这也很正常,计算运算符的优先级肯定要比比较运算符高,这是惯例。

4,直接用bool值作为下标

dat_all[

  (dat_all["objtype"] == "IV") |

  (dat_all["objtype"] == "III") 

]

这样也可以的,np的数组可以直接用和数组长度一样的0/1数组来表达对元素的选择。

除了这些常用的办法,你还有啥建议,欢迎留言。这篇主要针对初学者,大牛们就别嫌我讲基础知识了~~

另外,这里对纪录数组(结构体数组)就不多做介绍了,大家就假装看懂了吧……反正前面有一篇讲到了。

909aa2c8fcc3c929be5fc705cc8eae69.gif

欢迎关注“小林在线”

一个可能有点看不懂的公号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值