python 修改函数中列表的切片

问题描述 投票:0回答:4

考虑以下代码:

def func1(a):
    a[:] = [x**2 for x in a]

a = range(10)
print a  #prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
func1(a[:5])
print a  #also prints [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

我希望发送列表的一部分

a
并在函数内更改它。我的预期输出是

[0, 1, 4, 9, 16, 5, 6, 7, 8, 9]

哪种方式是惯用的方法?

谢谢!

python list slice
4个回答
6
投票

如果对列表进行切片,则仅修改副本,因此您想要做的事情不会以您想要的形式起作用。

但是您可以将可选的

slice
对象传递给
func1
,如果它不是
None
,则使用它来执行切片分配(否则使用
[:]

我会执行以下操作(使用

lambda
来避免复制/粘贴公式,并使用生成器表达式来避免创建无用的临时列表:

def func1(a,the_slice=None):
    e = lambda y : (x**2 for x in y)
    if the_slice:
        a[the_slice] = e(a[the_slice])
    else:
        a[:] = e(a)

测试:

a = list(range(10))
func1(a)
print(a)
a = list(range(10))
func1(a,slice(5))   # stop at 5
print(a)
a = list(range(10))
func1(a,slice(5,len(a),2))  # start at 5 / stop at the end, stride/step 2
print(a)

结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 25, 6, 49, 8, 81]
  • 在第一种情况下,列表的整体发生了变化
  • 第二种情况,只改变了前半部分。
  • 在第三种情况下,它改变了后半部分,但是2中的1个值(步长=2)

1
投票

这会起作用:

a = range(10)

a[:5] = [c**2 for c in a[:5]]

0
投票

a[:5]
创建一个新列表。因此,
func1
对其应用的更改不会反映在
a
中。您可以将切片添加到函数中:

def func1(a, start=None, stop=None, step=None):
    start = start if start is not None else 0
    stop = stop if stop is not None else len(a)
    step = step if step is not None else 1
    a[start:stop:step] = [x**2 for x in a[start:stop:step]]

func1(a, stop=5)

0
投票

在这里,为您解决了您的问题:)您的问题是重叠变量和不正确的切片

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.