python列表理解不起作用

时间:2014-10-21 07:05:23

标签: python list-comprehension for-comprehension

我有一个非常简单的问题:我需要为列表b中的每个索引将列表a中的值设置为1:

>>> a=[0, 0, 0, 0]
>>> b=[1, 3]

所需的结果将是:

[0, 1, 0, 1]

优雅的解决方案,如果python值得它的盐,当然是这样的:

>>> a[b]=1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not list

但当然这不起作用......所以我尝试了以下列表推导,但是它们都产生了相同的错误,好像理解是导致它(在for上):< / p>

首先是我真正期待的简单版本:

>>> a[x for x in b] = 1
  File "<stdin>", line 1
    a[x for x in b] = 1
          ^
SyntaxError: invalid syntax

然后是稍微复杂的版本:

>>> a[b[x] for x in range(0,len(b))] = 1
  File "<stdin>", line 1
    a[b[x] for x in range(0,len(b))] = 1
             ^
SyntaxError: invalid syntax

有人能看到这里发生了什么吗?

谢谢!

8 个答案:

答案 0 :(得分:5)

使用列表理解

In [1]: a=[0, 0, 0, 0]

In [2]: b=[1, 3]

In [3]: [ 1 if i in b else a_i for i, a_i in enumerate(a) ]
Out[3]: [0, 1, 0, 1]

“优雅的解决方案,如果python值得它的盐,将是这个”

导入一个模块,正如你所说,python是值得的:

In [1]: from numpy import array

In [2]: a = array([0, 0, 0, 0])

In [3]: b = [1, 3]

In [4]: a[b] = 1

In [5]: a
Out[5]: array([0, 1, 0, 1])

为了处理大量数据,numpy既优雅又快速。如果不使用numpy,那么Jonathan Hartnagel的for循环或类似Joel Cornett的BellsAndWhistlesList将是很好的解决方案。

答案 1 :(得分:3)

错误:

for i in b:
    a[i] = 1

或者,正如@ John1024所建议的,使用numpy

from numpy import array
a[b] = 1

答案 2 :(得分:1)

如果你想要这样的东西,请尝试numpy:

In [1]: import numpy

In [2]: a = numpy.zeros(4)

In [3]: b = numpy.array((1, 3))

In [4]: a[b] = 1

In [5]: a
Out[5]: array([ 0.,  1.,  0.,  1.])

或者像这样的普通Python解决方案:

a = [0] * 4
b = [1, 3]
for i in b:
    a[i] = 1

或者(缓慢而低效):

a = [0] * 4
b = [1, 3]
a = [i in b and 1 or a_i for i, a_i in enumerate(a)]

答案 3 :(得分:1)

使用列表理解:

a = [1 if i in b else v for i,v in enumerate(a) ]

输出:

[0, 1, 0, 1]

答案 4 :(得分:0)

[x for x in b] 

将创建:

[1, 3]

所以你的代码看起来像是:

a[1,3] = 1

哪个无效。

我不会为此使用列表理解,你可以简单地说:

for i in b:
    a[i] = 1

答案 5 :(得分:0)

我认为[1 if i in b else v for i,v in enumerate(a)]效率不高,因为它需要检查ibi中每个enumerate(a)是否for i in b: a[i] = 1

正如其他答案所说,for是最简单有效的方法,它只是直接设置所需的值。

但是,如果您不想使用map循环,则可以使用另一种方法>>> a=[0,0,0,0] >>> b=[1,3] >>> import functools >>> def set_index(x, l): ... l[x] = 1 ... >>> mapfunc = functools.partial(set_index, l=a) >>> map(mapfunc, b) [None, None] >>> a [0, 1, 0, 1] 代替它将操作应用于列表的所有元素。这个工具将为每个元素引入一个函数调用,所以也许它也不够高效。

{{1}}

答案 6 :(得分:0)

只是为了踢:

class BellsAndWhistlesList(list):
    def __setitem__(self, key, value):
        if hasattr(key, "__iter__") or hasattr(key, "next"):
            for i, v in zip(key, value):
                super(BellsAndWhistlesList, self).__setitem__(i, v)
        else:
            super(BellsAndWhistlesList, self).__setitem__(key, value)

答案 7 :(得分:0)

怎么样:

a = [0,0,0,0]
b = [1,3]

for i in range(len(b)):
    a[b[i]] = 1

print a # [0, 1, 0, 1]