10
$\begingroup$

Given two lists of unequal length:

ind = Range[0, 4];

color = {"red", "green", "blue", "black"};

how can I produce efficiently the following list which is as long as the shorter of the two?

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}
$\endgroup$
5
  • 1
    $\begingroup$ Use Transpose. $\endgroup$
    – C. E.
    Commented Mar 5, 2017 at 0:11
  • 2
    $\begingroup$ @C.E. Thanks for the comment but the lists do not have the same length. $\endgroup$
    – Dimitris
    Commented Mar 5, 2017 at 0:14
  • $\begingroup$ ok, I missed that. Then you have to shorten the first list to match the length of the second list. You could for example use Transpose[{color, Take[ind, Length[color]]}. $\endgroup$
    – C. E.
    Commented Mar 5, 2017 at 0:24
  • $\begingroup$ @C.E. Thanks again. I was wondering if there is a built-in function that "understands" that the two lists have different lengths and combines them in the proper manner, like zip function in Python. $\endgroup$
    – Dimitris
    Commented Mar 5, 2017 at 0:30
  • 3
    $\begingroup$ To closers: I think this is a legitimate question given that the lists are of unequal length. $\endgroup$
    – WReach
    Commented Mar 5, 2017 at 3:38

6 Answers 6

10
$\begingroup$

Some ideas:

Partition[Riffle[color, ind, {2, -1, 2}], 2]

Flatten[{color, ind}, {2}] // Cases[{_, _}]

{color, PadRight[ind, Length@color]}\[Transpose]

ind ~Riffle~ color ~Partition~ 2 ~Reverse~ 2

MapIndexed[{#, Extract[ind, #2]} &, color]

Take[#, All, Min[Length /@ #]]\[Transpose] &[{color, ind}]

All produce:

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

I'll note that the last method, which was perhaps my most serious attempt to answer this pragmatically, can be applied to any number of lists:

fn = Take[#, All, Min[Length /@ #]]\[Transpose] &;

fn[{{1, 2, 3}, Alphabet[], 2^Range@5}]
{{1, "a", 2}, {2, "b", 4}, {3, "c", 8}}
$\endgroup$
1
  • $\begingroup$ You have once again lived up to your username. $\endgroup$ Commented Mar 5, 2017 at 20:59
5
$\begingroup$

Here is a function to do it for any two lists. It doesn't care about the order in which the lists appear as arguments.

makePairs[a_List, b_List] :=
  Transpose[Take[#, Min[{Length @ a, Length @ b}]] & /@ {a, b}]

makePairs[color, ind]

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

makePairs[ind, color]

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

$\endgroup$
5
  • $\begingroup$ FWIW that's pretty similar to my last method: Take[#, All, Min[Length /@ #]]\[Transpose] & $\endgroup$
    – Mr.Wizard
    Commented Mar 5, 2017 at 6:23
  • 1
    $\begingroup$ @Mr.Wizard. The methods might be similar, but the programming philosophy illustrated by the two answer differ enough that I think this deserves to stand. $\endgroup$
    – m_goldberg
    Commented Mar 5, 2017 at 6:25
  • $\begingroup$ You mean you're not a fan of the shotgun answer? :^) $\endgroup$
    – Mr.Wizard
    Commented Mar 5, 2017 at 6:27
  • $\begingroup$ @Mr.Wizard. I like shotgun answers. I also think there should be room for other kinds. $\endgroup$
    – m_goldberg
    Commented Mar 5, 2017 at 6:35
  • $\begingroup$ No argument from me on that point! $\endgroup$
    – Mr.Wizard
    Commented Mar 5, 2017 at 6:55
5
$\begingroup$

Another variant:

DeleteCases[
 Transpose[PadRight[{color, ind}, Automatic, Missing]], {___, 
  Missing, ___}]
$\endgroup$
4
$\begingroup$
Block[{i = 1}, {#, ind[[i++]]} & /@ color]

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

$\endgroup$
1
$\begingroup$
n = Range[0, 4];

c = {"red", "green", "blue", "black"};

Using TransposeTableau by Ed Pegg Jr and Steven Skiena

TransposeTableau = ResourceFunction["TransposeTableau"];

Cases[{_, _}] @ TransposeTableau[{c, n}]

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

Cases[{_, _}] @ TransposeTableau[{{1, 2}, c}

{{1, "red"}, {2, "green"}}

$\endgroup$
1
$\begingroup$

ind = Range[0, 4]; color = {"red", "green", "blue", "black"};

Using GeneralizedMapThread by Sander Huisman:

GeneralizedMapThread = ResourceFunction["GeneralizedMapThread"];

Diagonal[GeneralizedMapThread[List, {color, ind}, 2]]

{{"red", 0}, {"green", 1}, {"blue", 2}, {"black", 3}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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