【问题标题】:python Modifying slice of list in functionpython在函数中修改列表切片
【发布时间】:2017-07-09 20:01:17
【问题描述】:

考虑以下代码:

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]

哪种方式是惯用的方式?

谢谢!

【问题讨论】:

  • @Kasramvd 由于另一个问题没有切片,我不相信这些是重复的。无论如何感谢您的参考...
  • 这是一个微不足道的区别,但主要问题是更改函数内部的可变对象可能会反映调用者。
  • @Kasramvd 我不同意。 before 我写了我的问题,但不确定在这些情况下处理切片的 pythonic 方法是什么。
  • @Kasramvd 仅供参考,我重新打开了,因为以前的欺骗链接只是相关的。我让你知道,因为我讨厌有人在我背后重新打开,但在这里我认为应该这样做。

标签: python list slice


【解决方案1】:

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)

【讨论】:

  • 难道没有一种方法可以在不影响索引的情况下执行这个想法吗?
  • 您可以分配给切片,但这不会改变fnc1(a[:5]) 将列表传递给fnc1 的事实,而该列表对原始a 一无所知。
【解决方案2】:

如果你对列表进行切片,你只修改了一个副本,所以你想做的事情不会以你想要的形式工作。

但是您可以将可选的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 值 (stride=2)

【讨论】:

    【解决方案3】:

    这将起作用:

    a = range(10)
    
    a[:5] = [c**2 for c in a[:5]]
    

    【讨论】:

    • 谢谢,我提出这个玩具示例是为了表达我更大的问题,因此这个直截了当的答案并没有真正帮助......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 2018-04-05
    • 2015-01-31
    • 2014-03-30
    • 2017-07-27
    • 2018-08-31
    相关资源
    最近更新 更多