Set Up

library(reticulate) # to use python in RStudio
library(tidyverse) # data wrangling and plotting with R

R code chunks are in light pink, while python in light blue.

Highlight


  • Slicing consecutive items in a list doesn’t give you the last item (example here)
  • After copying a list for save keeping, you might be surprised to find out that the copy will change along with the original list, since it is only an alias (or a Shallow Copy)
  • A copy that doesn’t change with the original is called a Deep Copy

Locating Elements in a List

Locating a Single Item

We can have diverse data types in a list (e.g., myList defined in the following code chunk contains both integers and a string).

Python uses 0-index. Therefore, to identify the first item in the list, we use [0] as the locator.

myList = [1,2,3,4,"five"]

myList[0] # this returns the first item in the list
## 1

Locating Consecutive Items

When you want to slice consecutive items from a list, note that the last item in the locator is not included.

myList[2] # this returns the 3rd item in the list
## 3
myList[0:2] # this returns the 1st to 2nd items in the list, the 3rd item is not included
## [1, 2]

Shallow vs Deep Copy

Shallow Copy


What surprised me more is this, when you make a copy of a list, the copy is only an alias, or a shallow copy. In the following example, you will see that changes made to the original list affect the copy, and vice versa.

This is really super surprising for me as an R user, coz R doesn’t do this (example).

myCopy = myList

myCopy[0] = "one, a change made in the copy"
myList[0]
## 'one, a change made in the copy'
myList[1] = "two, a change made in the original"
myCopy[1]
## 'two, a change made in the original'

Deep Copy


Guess I will just need to take note and remember this about Python lists. But how do I make a copy of a list that is a real copy rather than alias? It is really quite simple: Just make a deep copy by adding [:] at the end.

myList = [1,2,3,4,"five"]
myCopy = myList[:] # make a DEEP copy

myCopy[0] = "one, a change made in the copy"
myList[0]
## 1
myList[1] = "two, a change made in the original"
myCopy[1]
## 2

R

When you copy an R list, it is by default a deep copy rather than an alias. The copy and the original are independent from each other. Changes in one will not affect the other.

myList <- list(1,2,3,4,"five")
myCopy <- myList

myCopy[[1]] = "one, a change made in the copy"
myList[[1]]
## [1] 1
myList[[2]] = "two, a change made in the original"
myCopy[[2]]
## [1] 2