103

I want to make the equivalent of a python dict in R. Basically in python, I have:

visited = {}

if atom_count not in visited:
  Do stuff
  visited[atom_count] = 1

The idea is, if I saw that specific, atom_count, I have visited[atom_count] = 1. Thus, if I see that atom_count again, then I don't "Do Stuff". Atom_Count is an integer.

Thanks!

AndrewGB
  • 16,126
  • 5
  • 18
  • 49
user1357015
  • 11,168
  • 22
  • 66
  • 111

4 Answers4

99

The closest thing to a python dict in R is simply a list. Like most R data types, lists can have a names attribute that can allow lists to act like a set of name-value pairs:

> l <- list(a = 1,b = "foo",c = 1:5)
> l
$a
[1] 1

$b
[1] "foo"

$c
[1] 1 2 3 4 5

> l[['c']]
[1] 1 2 3 4 5
> l[['b']]
[1] "foo"

Now for the usual disclaimer: they are not exactly the same; there will be differences. So you will be inviting disappointment to try to literally use lists exactly the way you might use a dict in python.

joran
  • 169,992
  • 32
  • 429
  • 468
  • how can you programmatically iterate through such a list? the naive `l$names(l)[1]` obviously fails. i also haven't been able to get `l[which()]` to work – 3pitt Nov 16 '17 at 20:07
  • @MikePalmice Aside from a `for` loop, which is sort of an option in pretty much every language around, there is `lapply`. There are also related things with different syntax, like `Map`, and a whole package, **purrr** for lots of functional programming stuff. – joran Nov 16 '17 at 20:29
  • 1
    @MikePalmice, I think `l[[names(l)[1]]` should work. Anyway, you can just iterate like this: `l[[1]]` without using the names. Notice that single brackets `[]` will return a list, while double brackets `[[]]` will return the object inside the list. – Javi_VM Oct 08 '18 at 06:24
  • 1
    wow, such a simple thing in other languages is difficult in r? Let us say I have string contained in a variable. If I try to make it a key, it just picks the variable name as the key name instead of the value of the variable. – wondim Feb 16 '19 at 18:40
  • 2
    @wondim You can set list item names from a variable with `names(list) <- vector_of names`, subsetted assignment works as well, `names(list)[1] <- "foo"`. See also `setNames()`. – joran Feb 16 '19 at 18:54
  • @joran thanks! My challenge is populating it in a loop. – wondim Feb 16 '19 at 19:12
  • I tried using functions as first class members of my list, like I sometimes would in Python. That failed miserably, as every time I try to call the functions I get "Error: attempt to apply non-function". – David Nov 05 '22 at 07:31
  • 1
    @David `l <- list(a = sum,b = mean); l$a(1:3); l[['b']](1:3)` works I think. – joran Feb 25 '23 at 00:00
12

If, like in your case, you just want your "dictionary" to store values of the same type, you can simply use a vector, and name each element.

> l <- c(a = 1, b = 7, f = 2)
> l
a b f 
1 7 2

If you want to access the "keys", use names.

> names(l)
[1] "a" "b" "f"
user2739472
  • 1,401
  • 17
  • 15
5

I believe that the use of a hash table (creating a new environment) may be the solution to your problem. I'd type out how to do this but I just did so yesterday day at talkstats.com.

If your dictionary is large and only two columns then this may be the way to go. Here's the link to the talkstats thread with sample R code:

HASH TABLE LINK

Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
0

This way:

visited <- list()  
if (!(atom_count %in% names(visited))) {  
 Do stuff  
 visited[[as.character(atom_count)]] <- 1  
}
Colibri
  • 682
  • 6
  • 8