【问题标题】:Is python making a copy of my array in "for elem in A[a:b]"?python 是否在“for elem in A[a:b]”中复制我的数组?
【发布时间】:2021-11-10 14:46:48
【问题描述】:

当我做类似的事情时

for elem in A[a:b]:
  something(elem)

发生了什么? python是在内存中的某个地方复制我的数组,还是只是在选定的位置开始和结束?就内存使用而言,这是否与以下示例中使用 range() 相同?

for i in range(a,b):
  something(A[i])

【问题讨论】:

  • 对序列进行切片会返回它的副本——事实上,写seq[:] 是一种快速而简单的复制序列的方式。
  • 如果A 是一个列表,那么A[a:b] 正在创建一个包含A 指定切片的新列表。它与使用范围不同。
  • @arthll 定义“更好” - 处理速度?内存使用情况?代码整洁?
  • 这能回答你的问题吗? Does a slicing operation give me a deep or shallow copy? TL;DR 是的,它会复制列表
  • @arthll 这是一个全新的列表。列表实际上并不包含它们的对象,只是对它们的引用。需要明确的是,for 上下文不会改变任何东西。不客气!

标签: python


【解决方案1】:

取决于您称为“数组”的给定对象的类型。如果您的意思是内置类型 list - 是的,复制了一份:

>>> a = ['X', 'Y', 'Z']
>>> a
['X', 'Y', 'Z']
>>> b = a[0:2]
>>> b
['X', 'Y']
>>> a[0] = 42  # we modify `a`
>>> a
[42, 'Y', 'Z']
>>> b          # `b` did not change
['X', 'Y']

这同样适用于许多其他序列类型;例如,给bytearray

>>> ar = bytearray(b'XYZ')
>>> ar
bytearray(b'XYZ')
>>> ar2 = ar[0:2]
>>> ar2
bytearray(b'XY')
>>> ar[0] = 32  # we modify `a`
>>> ar
bytearray(b' YZ')
>>> ar2         # `ar2` did not change
bytearray(b'XY')

但有些类型并非如此;例如:

>>> ar = bytearray(b'XYZ')
>>> view = memoryview(ar)
>>> view
<memory at 0x...>
>>> view.tobytes()
b'XYZ'
>>> view2 = view[0:2]
>>> view2
<memory at 0x...>
>>> view2.tobytes()
b'XY'
>>> view[0] = 32  # this statement modifies both `view` and `view2`, and also `ar`!
>>> view.tobytes()
b' YZ'
>>> view2.tobytes()
b' Y'
>>> ar
bytearray(b' YZ')

就内存使用而言,这与使用 range() 的示例是否相同?

range()(或者,在 Python 2 中,xrange())是另一回事,因为它不存储其项目,而只存储 范围限制(即 start em> 和 stop) 以及可选的 step:

>>> range(1, 14, 2)  # items 1, 3, 5, 7, 9, 11, 13 are not stored in memory
range(1, 14, 2)
>>> range(1000000000000000000000)  # it does not take zillion bytes of memory :-)
range(0, 1000000000000000000000)

【讨论】:

    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多