Erlang/OTP Forums

Author Message

<  Erlang  ~  list comprehension question

bruceba
Posted: Wed Jul 11, 2007 3:43 pm Reply with quote
Joined: 11 Jul 2007 Posts: 3
Given two lists:
A = [1,2,3].
B = [4,5,6].

I want to generate:
AB = [[1,4],[2,5],[3,6]].

I can write this as a function but I'm sure there is a simple list comprehension to do the same task -- anybody have a clue stick?
View user's profile Send private message
Ulf
Posted: Wed Jul 11, 2007 5:26 pm Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
Code:

AB = [[lists:nth(X, A),lists:nth(X,B)] || X <- lists:seq(1, length(A))].


Will give you the result you want, but I guess it ain't the best way, really slow and not very clean.
View user's profile Send private message
Ulf
Posted: Wed Jul 11, 2007 5:54 pm Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
Should it work with list that doesn't have the same properties as A and B in the example?
View user's profile Send private message
karl
Posted: Wed Jul 11, 2007 6:02 pm Reply with quote
User Joined: 19 Oct 2006 Posts: 10 Location: London
How about:
Code:
[tuple_to_list(E) || E <- lists:zip([1,2,3], [4,5,6])]

_________________
http://www.erlang-consulting.com
View user's profile Send private message
bruceba
Posted: Wed Jul 11, 2007 6:13 pm Reply with quote
Joined: 11 Jul 2007 Posts: 3
karl wrote:
How about:
Code:
[tuple_to_list(E) || E <- lists:zip([1,2,3], [4,5,6])]


lists:zip looks like the right solution. Is it me or do others find the documentation difficult to navigate?
View user's profile Send private message
Ulf
Posted: Wed Jul 11, 2007 6:18 pm Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
But none of the solutions is as fast as a function to do it though, even if you save some lines Smile

The documentation where?
View user's profile Send private message
alexaandru
Posted: Wed Jul 11, 2007 7:26 pm Reply with quote
Benchmarking Hobbist Joined: 19 Jun 2007 Posts: 18 Location: Oradea, Romania
Of course Ulf was right Smile but it was still fun to try and benchmark this too Smile
Code:
-module(benchmarks_are_fun).
-export([test/1, loop/2]).
-define(A, [1,2,3]).
-define(B, [4,5,6]).
-define(Control, [[1,4],[2,5],[3,6]]).

map_zip(A, B) ->
    lists:map(fun({X,Y}) -> [X,Y] end, lists:zip(A,B)).

lc1(A, B) ->
    [[X,Y] || {X,Y} <- lists:zip(A,B)].

lc2(A, B) ->
    [tuple_to_list(X) || X <- lists:zip(A,B)].
   
lc3(A, B) ->
    [[lists:nth(X, A),lists:nth(X, B)] || X <- lists:seq(1, length(A))].

manual([Ha|Ta], [Hb|Tb]) ->
    manual(Ta, Tb, [[Ha,Hb]]).

manual([Ha|Ta], [Hb|Tb], Acc) ->
    manual(Ta, Tb, Acc ++ [[Ha,Hb]]);
manual([], [], Acc) ->
    Acc.

loop(0, Fun) ->
    Fun(?A, ?B);
loop(N, Fun) ->
    Fun(?A, ?B),
    loop(N - 1, Fun).

test(N) ->
    {Time1, Control} = timer:tc(benchmarks_are_fun, loop, [N, fun map_zip/2]),
    {Time2, Control} = timer:tc(benchmarks_are_fun, loop, [N, fun lc1/2]),
    {Time3, Control} = timer:tc(benchmarks_are_fun, loop, [N, fun lc2/2]),
    {Time4, Control} = timer:tc(benchmarks_are_fun, loop, [N, fun lc3/2]),
    {Time5, Control} = timer:tc(benchmarks_are_fun, loop, [N, fun manual/2]),
    {{map_zip, Time1},
     {list_comprehension_zip_and_pattern_matching, Time2},
     {list_comprehension_zip_tuple_to_list, Time3},
     {list_comprehension_nth, Time4},
     {manual_recursive, Time5}}.


And what I got on my system (compiled with HIPE) is:
Quote:
Erlang (BEAM) emulator version 5.5 [source] [async-threads:0] [hipe]

Eshell V5.5 (abort with ^G)
1> benchmarks_are_fun:test(1000).
{{map_zip,2423},
{list_comprehension_zip_and_pattern_matching,840},
{list_comprehension_tuple_to_list,1239},
{list_comprehension_nth,2752},
{manual_recursive,360}}
And yet again, using lists:nth proves to be the slowest possible thing to do.

Cheers,
Alex
View user's profile Send private message
bruceba
Posted: Wed Jul 11, 2007 10:45 pm Reply with quote
Joined: 11 Jul 2007 Posts: 3
Ulf wrote:
But none of the solutions is as fast as a function to do it though, even if you save some lines Smile

The documentation where?


Exactly! I'm used to a lisp enviroment where I can use #'apropos and #'describe to explore the available functions in the system (from within the REPL). Haven't tried distel yet.
View user's profile Send private message
alexaandru
Posted: Thu Jul 12, 2007 6:01 am Reply with quote
Benchmarking Hobbist Joined: 19 Jun 2007 Posts: 18 Location: Oradea, Romania
Code:
1> m(lists).
Module lists compiled: Date: May 28 2006, Time: 08.51
Compiler options:  [{cwd,"/builddir/build/BUILD/otp_src_R11B-0/lib/stdlib/src"},
                    {outdir,"/builddir/build/BUILD/otp_src_R11B-0/lib/stdlib/src/../ebin"},
                    {i,"/builddir/build/BUILD/otp_src_R11B-0/lib/stdlib/src/../include"},
                    {i,"/builddir/build/BUILD/otp_src_R11B-0/lib/stdlib/src/../../kernel/include"},
                    strict_record_tests,
                    debug_info]
Object file: /usr/lib/erlang/lib/stdlib-1.14/ebin/lists.beam
Exports:
all/2                         min/1
all/3                         module_info/0
any/2                         module_info/1
any/3                         nth/2
append/2                      nthtail/2
append/1                      partition/2
concat/1                      prefix/2
...

I just discovered this a couple of days ago Smile
help(). was most helpful in this regard.

Cheers,
Alex
View user's profile Send private message
Ulf
Posted: Thu Jul 12, 2007 8:19 am Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
Hum, of course, pattern matching when using zip.

Alex, our own benchmarking guru Cool
View user's profile Send private message
Ulf
Posted: Thu Jul 12, 2007 8:34 am Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
bruceba wrote:

Exactly! I'm used to a lisp enviroment where I can use #'apropos and #'describe to explore the available functions in the system (from within the REPL). Haven't tried distel yet.


I mainly use the man pages. I have basically no experience with Lisp so I don't know how those two functions work or what information they provide Smile
View user's profile Send private message
francesco
Posted: Thu Jul 12, 2007 9:37 am Reply with quote
User Joined: 07 Jul 2006 Posts: 249 Location: London
Hi Alex,

on top of m(..), you can also use Mod:module_info(), which will return an erlang data structure which can be used in programs and contains directives such as behavior, version and author. m/1 does not contain them.

Regarding the documentation, it has gotten much better in the past few years. Ericsson, after criticism from the community has made a huge effort to improve not just the tutorials and user guides, but also the way it is organized. Take a time machine and look at what we had to struggle with

http://www.erlang.org/documentation/doc-4.7.3/doc/index.html

If there is anything which does not exist, help is always welcome with HowTos on trapexit.

Regards,
Francesco
View user's profile Send private message Visit poster's website
alexaandru
Posted: Thu Jul 12, 2007 7:22 pm Reply with quote
Benchmarking Hobbist Joined: 19 Jun 2007 Posts: 18 Location: Oradea, Romania
Ulf wrote:
Hum, of course, pattern matching when using zip.

Alex, our own benchmarking guru Cool
Hehe... the advantage of being a newcomer: every problem is a mistery waiting... to be benchmarked! Very Happy

Cheers,
Alex
View user's profile Send private message
alexaandru
Posted: Thu Jul 12, 2007 7:40 pm Reply with quote
Benchmarking Hobbist Joined: 19 Jun 2007 Posts: 18 Location: Oradea, Romania
francesco wrote:
Hi Alex,

on top of m(..), you can also use Mod:module_info(), which will return an erlang data structure which can be used in programs and contains directives such as behavior, version and author. m/1 does not contain them.
Hi Francesco,
and thanks for tip Smile This already led me to an interesting discovery:

Code:

3> lists:module_info(attributes).
[{vsn,[6968511119412774106372288869712845437]},
 {deprecated,[{keymap,4},
              {all,3},
              {any,3},
              {map,3},
              {flatmap,3},
              {foldl,4},
              {foldr,4},
              {filter,3},
              {mapfoldl,4},
              {mapfoldr,4},
              {foreach,3}]}]

Are those methods really being deprecated?!? map, foldl, foldr, filter (don't care about foreach, haven't used it yet, I could get away with recursion or list comprehensions so far Very Happy) but map...? I like map Smile
Seriously now, if those are deprecated what is to be used instead? What will replace them?

francesco wrote:
Regarding the documentation, it has gotten much better in the past few years. Ericsson, after criticism from the community has made a huge effort to improve not just the tutorials and user guides, but also the way it is organized. Take a time machine and look at what we had to struggle with

http://www.erlang.org/documentation/doc-4.7.3/doc/index.html

If there is anything which does not exist, help is always welcome with HowTos on trapexit.

Regards,
Francesco

I really couldn't complain about the docs, from the contrary. erlang.org/doc/ + erl -man Mod gave me everything I needed. And that was even before I discovered trapexit Wink After that I _really_ couldn't complain at all Smile I especially liked the cookbook, just browsing it has really accelerated the learning process.

Have a really nice evening everyone,
Alex
View user's profile Send private message
Ulf
Posted: Fri Jul 13, 2007 10:34 am Reply with quote
User Joined: 04 Sep 2006 Posts: 42 Location: Göteborg
alexaandru wrote:
Hehe... the advantage of being a newcomer: every problem is a mistery waiting... to be benchmarked! Very Happy


And it is the best way to learn, to test stuff out and see what actually happens.
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 2
Goto page 1, 2  Next
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum