我有以下两个列表
l1 = {{{2011, 3, 13}, 1}, {{2011, 3, 14}, 1}, {{2011, 3, 15}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}; l2 = {{{2011, 3, 13}, 40}, {{2011, 3, 16}, 50}, {{2011, 3, 17}, 60}};
我需要从l2中提取项目,其日期(每个l2元素的第一个元素)与l1中的日期匹配(以便生成两个完全相同长度的列表)
我不明白为什么会这样:
Select[l1, MemberQ[Transpose[l2][[1]], #[[1]]]]
应该生成一个空列表。我错过了一些微不足道的事情吗?
答案 0 :(得分:7)
你忘记了&符号。它应该是
Select[l1, MemberQ[Transpose[l2][[1]], #[[1]]]&]
答案 1 :(得分:3)
Sjoerd向您展示如何使您的方法有效,但它不是最佳的。问题是,Transpose[l2][[1]]
中的每个元素都会再次评估l1
。大卫给出了一个方法,只执行一次该步骤。你也可以使用:
Cases[l1, {Alternatives @@ l2[[All, 1]], _}]
答案 2 :(得分:3)
更快的方法可以让您的列表变得更大:
DeleteCases[GatherBy[Join[l1, l2], First], {_}][[All, 1]]
(* Out= {{{2011, 3, 13}, 40}, {{2011, 3, 16}, 50}, {{2011, 3, 17}, 60}} *)
如果您的列表可能包含重复项,则可以使用
l1 = GatherBy[l1, First][[All, 1]]
首先删除重复项。
答案 3 :(得分:2)
这可能是你想到的吗?
dates=Transpose[l2][[1]];
Cases[l1, {x_, _} /; MemberQ[dates, x]]
答案 4 :(得分:1)
这是我的非排序交叉代码:
NonSortingIntersection[l1_, l2_, test_: SameQ] :=
Module[{res =
Last@Reap[
Scan[Extract[l1,
Position[l1, x_ /; test[x, #], {1}, 1, Heads -> False],
Sow] &, l2]]}, If[res === {}, res, First[res]]]
以下是用法:
In[22]:= NonSortingIntersection[l1, l2,
Function[{x, y}, First[x] == First[y]]]
Out[22]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
请注意,与其他解决方案不同,输出的长度不会超过l2
的长度。例如:
In[24]:= Cases[Join[l1, l1], {x_, _} /; MemberQ[Evaluate[Transpose[l2][[1]]], x]]
Out[24]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17},
3}, {{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
In[25]:= NonSortingIntersection[Join[l1, l1], l2,
Function[{x, y}, First[x] == First[y]]]
Out[25]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
这可能是也可能不是可取的,但这取决于谁更了解他的问题。