Perhaps something like this is what you're after?
df1 <- data.frame(year = 2006, x = 1:3)
df2 <- data.frame(year = 2007, x = 4:6)
df3 <- data.frame(year = 2006, x = 7:9)
df4 <- data.frame(year = 2007, x = 10:12)
l1 <- list(x2006 = df1, x2007 = df2)
l2 <- list(x2006 = df3, x2007 = df4)
lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]]))
####
[[1]]
  year x year x
1 2006 1 2006 7
2 2006 2 2006 8
3 2006 3 2006 9
[[2]]
  year x year  x
1 2007 4 2007 10
2 2007 5 2007 11
3 2007 6 2007 12
There may be other functions that would be more appropriate than cbind() such as merge(), but this should get you on the right path. This obviously assumes that you have named your lists and those names are consistent between l1 and l2.
EDITED TO ADD SOME MORE CONTEXT
There are a few key assumptions that make this work. Those assumptions are:
- Your list objects have names
- The namesin each list are consistent between lists
So, what are the names I'm referring to? If you look at the code about where I define l1, you'll see x2006 = df1 and x2007 = df2. I'm defining two objects in that list, df1 and df2 with two names x2006 and x2007.
You can check the names of the list by asking for the names():
names(l1)
####
[1] "x2006" "x2007"
The other key assumption is that you can index objects in a list by their name, using the [[ function. For example:
l1[["x2006"]]
####
  year x
1 2006 1
2 2006 2
3 2006 3
So what we're doing with the lapply function is that we're iterating over the names of l1, defining an anonymous function, and then using the [[ function to index the two list objects l1 and l2. We're currently using cbind as the function, but you can replace cbind with almost any other function.
As I mentioned above, this assumes that the names are the same between the two or more list objects. For example, this does not work:
#change the names of the l2 list
names(l2) <- c("foo", "bar")
lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]]))
####
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 3, 0
The names however do not have to be in the same order. That's where the benefit of the [[ function comes in. To wit:
#Fix names on l2 again
names(l2) <- c("x2006", "x2007")
l2reverse <- list(x2007 = df4, x2006 = df3)
all.equal(
  lapply(names(l1), function(x) cbind(l1[[x]], l2[[x]])),  
  lapply(names(l1), function(x) cbind(l1[[x]], l2reverse[[x]]))
)
####
[1] TRUE