1

I know this doesn't work, but it illustrates my goal. If I have a list C, and I set A=C, then they point to the same object, which is what I want. But if I set A to a subset of C, then it creates a new list. I don't want that. I want it to point to the same data. E.g:

C = [1,2,3,4,5,6]
A = C[3:6]
C[4] = 9
print(C)
print(A)

I would like to see [4,9,6] for A

TPM
  • 834
  • 4
  • 9
  • 20
  • 2
    Lists don't support that. It wouldn't interact well with resizing and element shifting anyway. – user2357112 May 12 '20 at 21:12
  • 1
    Do you have a practical use case for this? It sounds like a bad idea, even if Python supported it. – Jongware May 12 '20 at 21:39
  • The statement: "But if I set A to a subset of C, then it creates a new list" is not correct as [this answer](https://stackoverflow.com/questions/5131538/slicing-a-list-in-python-without-generating-a-copy) illustrates. What has happened is with C[4]=9, one of its references in its lists changes. However, the references for list A don't change so it has the old values. – DarrylG May 12 '20 at 21:39
  • 2
    This smells like an X-Y question: what’s the real problem that you think this is (would be) a solution to? – DisappointedByUnaccountableMod May 12 '20 at 21:40

1 Answers1

2

Python lists don't do that. It's something numpy arrays do:

In [123]: import numpy as np

In [124]: c = np.array([1,2,3,4,5,6])

In [125]: c
Out[125]: array([1, 2, 3, 4, 5, 6])

In [126]: a = c[3:6]

In [127]: a
Out[127]: array([4, 5, 6])

In [128]: c[4] = 9

In [129]: c
Out[129]: array([1, 2, 3, 4, 9, 6])

In [130]: a
Out[130]: array([4, 9, 6])

You could do that with Python lists if each element was also a list or any mutable object:

>>> c = [[1], [2], [3], [4], [5], [6]]  # list of lists
>>> a = c[3:6]
>>> a
[[4], [5], [6]]
>>> c[4].append(9)
>>> c
[[1], [2], [3], [4], [5, 9], [6]]
>>> a  # has also changed
[[4], [5, 9], [6]]
>>> c[4].pop(0)  # remove the first element of c[4]
5
>>> a
[[4], [9], [6]]
>>>

But you can't "overwrite" the value of c[4], only change it. Hence, works only with mutable objects that are themselves being changed.

>>> c[4] = 0
>>> c
[[1], [2], [3], [4], 0, [6]]
>>> a  # does not have the 0, retains previous value
[[4], [9], [6]]
>>>
aneroid
  • 12,983
  • 3
  • 36
  • 66
  • I should not have included the constraint that the solution needed to be a list. The numpy array does exactly what I want, and that is what I will implement. Thank you for realizing what I was after. – TPM May 13 '20 at 15:25
  • Actually, if you had not specified "list" and said something vague like "ordered iterable container-type where the slices only return views", I would not have thought of the numpy option before closing the tab :-) One possible alternate solution _is_ to write your own "ordered iterable container-type where the slices only return views". But that's a lot more effort to do correctly. _(Hint: make [`__getitem__`](https://docs.python.org/3/reference/datamodel.html#object.__getitem__) return a proxy/view when the parameter is a slice.)_ – aneroid May 13 '20 at 18:31
  • Also, ppl here don't typically answer Python question with numpy solutions unless numpy is specifically mentioned. I consider that **a good thing** because of how differently numpy arrays can behave vs Python's container types; as well as the various numpy methods which don't exist for Python lists. If one were writing a larger Python program and then had a problem in one small area with only numpy-based answers on SO, they'd end up needing to install and/or import numpy for just one piece of code, which is a bit silly for external packages. – aneroid May 13 '20 at 18:35