使用这个setitem函数克服列表理解限制是否非常单一?

Ton*_*nen 2 python list-comprehension side-effects variable-assignment

>>> a=range(5)
>>> [a[i] for i in range(0,len(a),2)] ## list comprehension for side effects
[0, 2, 4]
>>> a
[0, 1, 2, 3, 4]
>>> [a[i]=3 for i in range(0,len(a),2)] ## try to do assignment
SyntaxError: invalid syntax
>>> def setitem(listtochange,n,value):  ## function to overcome limitation
    listtochange[n]=value
    return value

>>> [setitem(a,i,'x') for i in range(0,len(a),2)] ## proving the function
['x', 'x', 'x']
>>> a 
['x', 1, 'x', 3, 'x']   # We did assignment anyway
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 26

不要使用列表推导来执行副作用 - 这不是Pythonic.改为使用显式循环:

for i in range(0,len(a),2):
    a[i] = 3
Run Code Online (Sandbox Code Playgroud)

除了列表推导中的副作用令人惊讶和意外之外,您正在构建一个您从未使用的结果列表,这在此非常浪费且完全没有必要.

  • 我希望我能不止一次地赞成这一点.并且不要调用你的函数`set`. (9认同)

ken*_*ytm 9

是.我推荐使用

a[::2] = ['x'] * len(a[::2])
Run Code Online (Sandbox Code Playgroud)

代替.


编辑:

Python 2.6的微博客:

~:249$ python2.6 -m timeit -s 'a = range(2000)' 'a[::2] = [8] * len(a[::2])'
10000 loops, best of 3: 26.2 usec per loop

~:250$ python2.6 -m timeit -s 'a = range(2000)' 'a[::2] = [8] * (len(a)/2)'
10000 loops, best of 3: 19.6 usec per loop

~:251$ python2.6 -m timeit -s 'a = range(2000)' 'for i in xrange(0,len(a),2): a[i] = 8'
10000 loops, best of 3: 92.1 usec per loop

~:252$ python2.6 -m timeit -s 'a = range(2000)
> def assign(x,i,v):x[i]=v;return v' '[assign(a,i,8) for i in xrange(0, len(a), 2)]'
1000 loops, best of 3: 336 usec per loop
Run Code Online (Sandbox Code Playgroud)

Python 3.1:

~:253$ python3.1 -m timeit -s 'a = list(range(2000))' 'a[::2] = [8] * len(a[::2])'
100000 loops, best of 3: 19.8 usec per loop

~:254$ python3.1 -m timeit -s 'a = list(range(2000))' 'a[::2] = [8] * (len(a)//2)'
100000 loops, best of 3: 13.4 usec per loop

~:255$ python3.1 -m timeit -s 'a = list(range(2000))' 'for i in range(0,len(a),2): a[i] = 8'
10000 loops, best of 3: 119 usec per loop

~:256$ python3.1 -m timeit -s 'a = list(range(2000))
> def assign(x,i,v):x[i]=v;return v' '[assign(a,i,8) for i in range(0, len(a), 2)]'
1000 loops, best of 3: 361 usec per loop
Run Code Online (Sandbox Code Playgroud)