Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Python supports a concept called "list comprehensions".

Following is sample example

A=[[1,2,3], [2,3,4], [3,4,5]]
print( [ a + [i]  for a in A for i in range(1,4) if i in a] )
[[1, 2, 3, 1], [1, 2, 3, 2], [1, 2, 3, 3], [2, 3, 4, 2], [2, 3, 4, 3], [3, 4, 5, 3]]

What's the most natural way to translate this Python code to Mathematica? I have the following method:

A = {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}};
Select[ Table[ a ~ Join ~ {i}, {a, A}, {i, 3}] ~ Flatten ~ 1, MemberQ[ Most @ #, Last @ #]&]

but I think it's neither fast nor elegant, therefore I am looking for a better way.

share|improve this question
    
The same article you linked has a few lines about Mathematica too. –  belisarius Nov 28 '13 at 12:05
    
Maybe this? –  Oleksandr R. Nov 28 '13 at 13:03
add comment

4 Answers

up vote 10 down vote accepted

This one is very close to your Python code

Join @@ Table[Append[a, i], {a, A}, {i, Intersection[Range[3], a]}]
{{1, 2, 3, 1}, {1, 2, 3, 2}, {1, 2, 3, 3}, {2, 3, 4, 2}, {2, 3, 4, 3}, {3, 4, 5, 3}}
share|improve this answer
add comment
A = {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}};
Join @@ Table[If[a~MemberQ~i, a~Join~{i}, Unevaluated[]], {a, A}, {i, 3}]
Join @@ Table[a~Join~{i}, {a, A}, {i, Select[Range@3, a~MemberQ~# &]}]

{{1, 2, 3, 1}, {1, 2, 3, 2}, {1, 2, 3, 3}, {2, 3, 4, 2}, {2, 3, 4, 3}, {3, 4, 5, 3}}

share|improve this answer
1  
+1 for writing Unevaluated[] instead of Unevaluated[Sequence[]], or ##&[] :) –  Jacob Akkerboom Nov 28 '13 at 14:32
    
@Jacob What's wrong with my "vanishing function" ##&[]? (+1, by the way) –  Mr.Wizard Nov 28 '13 at 16:30
1  
@Mr.Wizard haha nothing really, in fact I was glad to show off that I knew about it :P. But also despite all the talk about this, I may have missed the option of just using Unevaluated[], so I guess I learned something :). –  Jacob Akkerboom Nov 28 '13 at 16:49
    
@Jacob I attempted to cover that in this answer but I guess I should have been more explicit. I said that "All of these heads meet this requirement:" and listed Unevaluated and ## & -- both would be used the same way: Unevaluated[] and ## &[]. –  Mr.Wizard Nov 29 '13 at 12:20
    
@Mr.Wizard that one is a nice answer (as I suppose you can tell by the badge :P). I'm not very focussed right now, but perhaps an additional point of confusion could by that neither Apply[] nor Symbol[] evaluate to Sequence[] (anymore?). –  Jacob Akkerboom Nov 29 '13 at 12:42
show 2 more comments

Some of the other approaches might be much more efficient, but the following shows how one can create something which is probably as easy to read (if one is fluent in Mathematica) as a python list comprehension:

SetAttributes[listComprehend, HoldAll]

listComprehend[Verbatim[Condition][body_, crit_],iters:({_, __}..)] := Flatten[
    Table[
        If[crit, body, Unevaluated[Sequence[]]],
        iterators
    ], 1]

use it like this:

listComprehend[Append[a, i] /; MemberQ[a, i], {a, A}, {i, 3}]

/; is the shortcut for Condition and usually can be read as "provided that" in mathematica code. Doing so, the above seems to be relatively clear code. Unfortunately the translation to one of the potentially more efficient approaches is not that simple...

share|improve this answer
add comment

Not really sure if you're after the functionality, the way to generate your list, or some performance improvement. Anyway:

Cases[Outer[Join, A, List /@ Range@Length @A, 1], {___, x_, ___, x_}, 2]
(*
 {{1, 2, 3, 1}, {1, 2, 3, 2}, {1, 2, 3, 3}, 
  {2, 3, 4, 2}, {2, 3, 4, 3}, {3, 4, 5, 3}}
*)

Edit

For efficiency, you may want to generate only the final elements, without the need to post filter them:

Flatten[Function[{u}, Table[Join[u, {i}], {i, u}]][#] & /@ A, 1]

or:

Flatten[Function[{u}, ReplaceList[#, Thread[x_ :> Flatten[{x, #}] & /@ u]]][#] & /@ A, 1]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.