简体   繁体   English

迭代数组

[英]Iterating through array

I have an array of bools and now I want to swap those entries for numbers. 我有一系列bools,现在我想将这些条目换成数字。

False => 0
True => 1

I have written two different pieces of code and I would like to know, which one is better and why. 我写了两段不同的代码,我想知道哪一个更好,为什么。 This is not so much about actually solving the problem, as about learning. 这不是关于实际解决问题,而是关于学习。

arr = [[True,False],[False,True],[True,True]]

for i,row in enumerate(arr):
    for j,entry in enumerate(row):
        if entry:
            arr[i][j] = 1
        else:
            arr[i][j] = 0
print(arr)

And the second approach: 第二种方法:

arr = [[True,False],[False,True],[True,True]]

for i in range(len(arr)):
    for j in range(len(arr[i])):
        if arr[i][j]:
            arr[i][j] = 1
        else:
            arr[i][j] = 0    
print(arr)

I read that there are ways to do this with importing itertools or similar. 我读到有很多方法可以通过导入itertools或类似方法来实现。 I am really not a fan of importing things if it can be done with “on-board tools”, but should I rather be using them for this problem? 如果可以使用“板载工具”,我真的不喜欢导入东西,但我是否应该使用它们来解决这个问题?

Let's define your array: 让我们定义你的数组:

>>> arr = [[True,False],[False,True],[True,True]]

Now, let's convert the booleans to integer: 现在,让我们将布尔值转换为整数:

>>> [[int(i) for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]

Alternatively, if we want to be more flexible about what gets substituted in, we can use a ternary statement: 或者,如果我们想要更加灵活地替换什么,我们可以使用三元语句:

>>> [[1 if i else 0 for i in row] for row in arr]
[[1, 0], [0, 1], [1, 1]]

If you want to stay with a for-loop (eg because you want to mutate the existing array instead of creating a new one), you should simplify the code. 如果你想继续使用for循环(例如,因为你想改变现有的数组而不是创建一个新数组),你应该简化代码。

I would first simplify the outer loop by removing the indexing (there is no need for it since it's even easier to modify a row than a nested array): 我首先通过删除索引来简化外部循环(不需要它,因为它比嵌套数组更容易修改行):

for row in arr:
    for j, entry in enumerate(row):
        if entry:
            row[j] = 1
        else:
            row[j] = 0

these kinds of simple if statement can often be simplified by using an if expression: 通过使用if表达式,通常可以简化这些简单的if语句:

 row[j] = 1 if entry else 0

but in this case we can do even better. 但在这种情况下,我们可以做得更好。 bool is a subclass of int (ie. all bool 's are int 's), and True and False are defined to be exactly 1 and 0 respectively -- if you scroll down to the specification section of PEP 285 ( https://www.python.org/dev/peps/pep-0285/ ) you'll see that that equivalence is not accidental but very much by design. boolint的子类(即所有bool都是int的),而TrueFalse分别定义为10 - 如果向下滚动到PEP 285的规范部分( https:// www.python.org/dev/peps/pep-0285/ )你会发现这种等价不是偶然的,而是非常多的设计。

We can therefore use the int constructor to grab the underlying integer values[*], since int(True) == 1 and int(False) == 0 , the if-expression can be simplified to: 因此我们可以使用int构造函数来获取底层整数值[*],因为int(True) == 1int(False) == 0 ,if-expression可以简化为:

row[j] = int(entry)

[*] technically this is an explicit upcast to a base class, and not a conversion constructor.. [*]从技术上讲,这是对基类的显式向上转换,而不是转换构造函数。

The simplified code: 简化代码:

for row in arr:
    for j, entry in enumerate(row):
        row[j] = int(entry)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM