Given an arbitrarily nested list, how can I find if a list contains empty lists? Consider the following example:
mylist <- list(list("foo", "bar", "baz", list(list())))
I tried rapply
, but that skips through lists. While I could use lapply
, I'd need to know the level of nesting beforehand. For this exercise, I don't need to know where the list is (although that would be a bonus), I just need a way to detect if there is one.
Use the any() function. This returns True if any list within the list is not empty. alist = [[],[]] if not any(alist): print("Empty list!") >> Empty list!
Short answer: You can remove all empty lists from a list of lists by using the list comprehension statement [x for x in list if x] to filter the list.
x = [], x[4] = 1 works in perl, throws an error in python). however, just make x a dictionary, and it will work the same way: x = {}, x[4] = 1 now works just fine. you will have to sort the keys, and they won't be monotonic though (i.e. you could have indexes like [0,3,4,7]).
You can create an empty list using an empty pair of square brackets [] or the type constructor list() , a built-in function that creates an empty list when no arguments are passed. Square brackets [] are commonly used in Python to create empty lists because it is faster and more concise.
Another approach is to use rrapply
in the rrapply
-package (an extension of base-rrapply
):
library(rrapply)
## check if any empty list exists
any(
rrapply(mylist,
classes = "list",
condition = function(x) length(x) < 1,
f = function(x) TRUE,
deflt = FALSE,
how = "unlist"
)
)
#> [1] TRUE
It is straightforward to update the above call to return the index vectors of any empty lists:
## return flat list with position vectors of empty list
rrapply(mylist,
classes = "list",
condition = function(x) length(x) < 1,
f = function(x, .xpos) .xpos,
how = "flatten"
)
#> [[1]]
#> [1] 1 4 1
Here, we make use of the .xpos
argument which evaluates to the position of the current list element under evaluation.
Note that this automatically returns all empty list positions instead of only one:
mylist2 <- list(list("foo", list(), "baz", list(list())))
rrapply(mylist2,
classes = "list",
condition = function(x) length(x) < 1,
f = function(x, .xpos) .xpos,
how = "flatten"
)
#> [[1]]
#> [1] 1 2
#>
#> [[2]]
#> [1] 1 4 1
## using MrFlick's find_empty_list function
find_empty_list(mylist2)
#> [1] 1 4 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With