Erlang列表 #

一、列表概述 #

列表是Erlang中最常用的数据结构之一,用于存储有序的元素集合。

1.1 列表的本质 #

列表由头(Head)和尾(Tail)组成,尾也是一个列表:

erlang
-module(list_essence).
-export([demo/0]).

demo() ->
    List = [1, 2, 3, 4, 5],
    [Head | Tail] = List,
    io:format("List: ~p~n", [List]),
    io:format("Head: ~p~n", [Head]),
    io:format("Tail: ~p~n", [Tail]),
    ok.

1.2 列表定义 #

erlang
-module(list_def).
-export([demo/0]).

demo() ->
    Empty = [],
    Numbers = [1, 2, 3],
    Mixed = [1, "hello", atom, {tuple}],
    Nested = [[1, 2], [3, 4]],
    io:format("Empty: ~p~n", [Empty]),
    io:format("Numbers: ~p~n", [Numbers]),
    io:format("Mixed: ~p~n", [Mixed]),
    io:format("Nested: ~p~n", [Nested]),
    ok.

二、列表构造 #

2.1 使用|操作符 #

erlang
-module(list_construct).
-export([demo/0]).

demo() ->
    List1 = [1 | [2, 3]],
    List2 = [1, 2 | [3]],
    List3 = [1, 2, 3 | []],
    io:format("List1: ~p~n", [List1]),
    io:format("List2: ~p~n", [List2]),
    io:format("List3: ~p~n", [List3]),
    ok.

2.2 添加元素 #

erlang
-module(add_element).
-export([demo/0]).

demo() ->
    List = [2, 3, 4],
    NewList = [1 | List],
    io:format("Original: ~p~n", [List]),
    io:format("After add: ~p~n", [NewList]),
    ok.

2.3 列表连接 #

erlang
-module(list_concat).
-export([demo/0]).

demo() ->
    List1 = [1, 2],
    List2 = [3, 4],
    Combined = List1 ++ List2,
    io:format("List1: ~p~n", [List1]),
    io:format("List2: ~p~n", [List2]),
    io:format("Combined: ~p~n", [Combined]),
    ok.

2.4 列表减法 #

erlang
-module(list_subtract).
-export([demo/0]).

demo() ->
    List1 = [1, 2, 3, 2, 1],
    List2 = [1, 2],
    Result = List1 -- List2,
    io:format("List1: ~p~n", [List1]),
    io:format("List2: ~p~n", [List2]),
    io:format("Result: ~p~n", [Result]),
    ok.

三、列表模式匹配 #

3.1 提取头尾 #

erlang
-module(list_pattern).
-export([demo/0]).

demo() ->
    [H | T] = [1, 2, 3, 4, 5],
    io:format("Head: ~p~n", [H]),
    io:format("Tail: ~p~n", [T]),
    
    [A, B | Rest] = [1, 2, 3, 4, 5],
    io:format("A: ~p~n", [A]),
    io:format("B: ~p~n", [B]),
    io:format("Rest: ~p~n", [Rest]),
    ok.

3.2 匹配特定元素 #

erlang
-module(match_specific).
-export([demo/0]).

demo() ->
    [First, Second, Third] = [a, b, c],
    io:format("First: ~p~n", [First]),
    io:format("Second: ~p~n", [Second]),
    io:format("Third: ~p~n", [Third]),
    ok.

3.3 忽略元素 #

erlang
-module(ignore_elements).
-export([first/1, second/1, last/1]).

first([H | _]) -> H.

second([_, H | _]) -> H.

last([H]) -> H;
last([_ | T]) -> last(T).

四、lists模块 #

4.1 基本函数 #

erlang
-module(lists_basic).
-export([demo/0]).

demo() ->
    List = [3, 1, 4, 1, 5, 9, 2, 6],
    
    Len = length(List),
    Rev = lists:reverse(List),
    Sort = lists:sort(List),
    Sum = lists:sum(List),
    
    io:format("Original: ~p~n", [List]),
    io:format("Length: ~p~n", [Len]),
    io:format("Reverse: ~p~n", [Rev]),
    io:format("Sort: ~p~n", [Sort]),
    io:format("Sum: ~p~n", [Sum]),
    ok.

4.2 查找函数 #

erlang
-module(lists_find).
-export([demo/0]).

demo() ->
    List = [1, 2, 3, 4, 5],
    
    Member = lists:member(3, List),
    Nth = lists:nth(3, List),
    Pos = lists:position(3, List),
    Keyfind = lists:keyfind(a, 1, [{a, 1}, {b, 2}]),
    
    io:format("member(3): ~p~n", [Member]),
    io:format("nth(3): ~p~n", [Nth]),
    io:format("position(3): ~p~n", [Pos]),
    io:format("keyfind(a): ~p~n", [Keyfind]),
    ok.

4.3 过滤函数 #

erlang
-module(lists_filter).
-export([demo/0]).

demo() ->
    List = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    
    Even = lists:filter(fun(X) -> X rem 2 =:= 0 end, List),
    Odd = lists:filter(fun(X) -> X rem 2 =:= 1 end, List),
    Partition = lists:partition(fun(X) -> X > 5 end, List),
    
    io:format("Original: ~p~n", [List]),
    io:format("Even: ~p~n", [Even]),
    io:format("Odd: ~p~n", [Odd]),
    io:format("Partition: ~p~n", [Partition]),
    ok.

4.4 映射函数 #

erlang
-module(lists_map).
-export([demo/0]).

demo() ->
    List = [1, 2, 3, 4, 5],
    
    Doubled = lists:map(fun(X) -> X * 2 end, List),
    Squared = lists:map(fun(X) -> X * X end, List),
    
    io:format("Original: ~p~n", [List]),
    io:format("Doubled: ~p~n", [Doubled]),
    io:format("Squared: ~p~n", [Squared]),
    ok.

4.5 折叠函数 #

erlang
-module(lists_fold).
-export([demo/0]).

demo() ->
    List = [1, 2, 3, 4, 5],
    
    Sum = lists:foldl(fun(X, Acc) -> X + Acc end, 0, List),
    Product = lists:foldl(fun(X, Acc) -> X * Acc end, 1, List),
    Reversed = lists:foldl(fun(X, Acc) -> [X | Acc] end, [], List),
    
    io:format("Original: ~p~n", [List]),
    io:format("Sum: ~p~n", [Sum]),
    io:format("Product: ~p~n", [Product]),
    io:format("Reversed: ~p~n", [Reversed]),
    ok.

4.6 常用函数列表 #

函数 说明
length/1 列表长度
hd/1 获取头元素
tl/1 获取尾列表
lists:reverse/1 反转列表
lists:sort/1 排序
lists:sum/1 求和
lists:concat/1 连接元素
lists:flatten/1 展平嵌套列表
lists:member/2 检查成员
lists:nth/2 获取第N个元素
lists:append/2 连接列表
lists:delete/2 删除元素
lists:filter/2 过滤
lists:map/2 映射
lists:foldl/3 左折叠
lists:foldr/3 右折叠
lists:foreach/2 遍历执行
lists:all/2 全部满足
lists:any/2 任一满足
lists:zip/2 配对
lists:unzip/1 解配对

五、递归处理列表 #

5.1 遍历列表 #

erlang
-module(list_traverse).
-export([print_all/1]).

print_all([]) -> ok;
print_all([H | T]) ->
    io:format("~p~n", [H]),
    print_all(T).

5.2 计算长度 #

erlang
-module(list_length).
-export([my_length/1]).

my_length([]) -> 0;
my_length([_ | T]) -> 1 + my_length(T).

5.3 求和 #

erlang
-module(list_sum).
-export([my_sum/1]).

my_sum([]) -> 0;
my_sum([H | T]) -> H + my_sum(T).

5.4 反转 #

erlang
-module(list_reverse).
-export([my_reverse/1]).

my_reverse(List) -> my_reverse(List, []).

my_reverse([], Acc) -> Acc;
my_reverse([H | T], Acc) -> my_reverse(T, [H | Acc]).

5.5 过滤 #

erlang
-module(list_filter).
-export([my_filter/2]).

my_filter(_, []) -> [];
my_filter(Pred, [H | T]) ->
    case Pred(H) of
        true -> [H | my_filter(Pred, T)];
        false -> my_filter(Pred, T)
    end.

5.6 映射 #

erlang
-module(list_map).
-export([my_map/2]).

my_map(_, []) -> [];
my_map(Fun, [H | T]) -> [Fun(H) | my_map(Fun, T)].

六、列表推导式 #

6.1 基本语法 #

erlang
-module(list_comprehension).
-export([demo/0]).

demo() ->
    Numbers = [1, 2, 3, 4, 5],
    
    Doubled = [X * 2 || X <- Numbers],
    Squared = [X * X || X <- Numbers],
    Evens = [X || X <- Numbers, X rem 2 =:= 0],
    
    io:format("Original: ~p~n", [Numbers]),
    io:format("Doubled: ~p~n", [Doubled]),
    io:format("Squared: ~p~n", [Squared]),
    io:format("Evens: ~p~n", [Evens]),
    ok.

6.2 多个生成器 #

erlang
-module(multi_generator).
-export([demo/0]).

demo() ->
    Pairs = [{X, Y} || X <- [1, 2, 3], Y <- [a, b]],
    io:format("Pairs: ~p~n", [Pairs]),
    ok.

6.3 带条件 #

erlang
-module(with_guard).
-export([demo/0]).

demo() ->
    Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    EvenSquares = [X * X || X <- Numbers, X rem 2 =:= 0],
    io:format("Even squares: ~p~n", [EvenSquares]),
    ok.

6.4 嵌套列表 #

erlang
-module(nested_comp).
-export([demo/0]).

demo() ->
    Nested = [[1, 2], [3, 4], [5, 6]],
    Flattened = [X || SubList <- Nested, X <- SubList],
    io:format("Nested: ~p~n", [Nested]),
    io:format("Flattened: ~p~n", [Flattened]),
    ok.

七、列表与字符串 #

7.1 字符串是列表 #

erlang
-module(string_as_list).
-export([demo/0]).

demo() ->
    Str = "hello",
    [H | T] = Str,
    io:format("String: ~p~n", [Str]),
    io:format("Head char: ~c (~p)~n", [H, H]),
    io:format("Tail: ~s~n", [T]),
    ok.

7.2 字符串处理 #

erlang
-module(string_list_ops).
-export([uppercase/1, lowercase/1]).

uppercase(Str) -> [char:to_upper(C) || C <- Str].

lowercase(Str) -> [char:to_lower(C) || C <- Str].

八、性能考虑 #

8.1 头部操作高效 #

erlang
-module(perf_head).
-export([demo/0]).

demo() ->
    List = lists:seq(1, 10000),
    
    AddHead = [0 | List],
    
    AddTail = List ++ [0],
    
    io:format("Add to head: fast~n"),
    io:format("Add to tail: slow~n"),
    ok.

8.2 避免频繁++ #

erlang
-module(avoid_concat).
-export([bad/1, good/1]).

bad(List) ->
    lists:foldl(fun(X, Acc) -> Acc ++ [X] end, [], List).

good(List) ->
    lists:reverse(lists:foldl(fun(X, Acc) -> [X | Acc] end, [], List)).

8.3 使用尾递归 #

erlang
-module(tail_recursive).
-export([sum_bad/1, sum_good/1]).

sum_bad([]) -> 0;
sum_bad([H | T]) -> H + sum_bad(T).

sum_good(List) -> sum_good(List, 0).

sum_good([], Acc) -> Acc;
sum_good([H | T], Acc) -> sum_good(T, H + Acc).

九、实用函数 #

9.1 查找元素 #

erlang
-module(find_utils).
-export([find/2, find_index/2]).

find(_, []) -> not_found;
find(Value, [Value | _]) -> {found, Value};
find(Value, [_ | T]) -> find(Value, T).

find_index(Value, List) -> find_index(Value, List, 1).

find_index(_, [], _) -> not_found;
find_index(Value, [Value | _], Index) -> {found, Index};
find_index(Value, [_ | T], Index) -> find_index(Value, T, Index + 1).

9.2 去重 #

erlang
-module(unique).
-export([unique/1]).

unique(List) -> unique(List, []).

unique([], Acc) -> lists:reverse(Acc);
unique([H | T], Acc) ->
    case lists:member(H, Acc) of
        true -> unique(T, Acc);
        false -> unique(T, [H | Acc])
    end.

9.3 分组 #

erlang
-module(group).
-export([group_by/2]).

group_by(N, List) when N > 0 -> group_by(N, List, []).

group_by(_, [], Acc) -> lists:reverse(Acc);
group_by(N, List, Acc) ->
    {Group, Rest} = split_n(N, List),
    group_by(N, Rest, [Group | Acc]).

split_n(N, List) -> split_n(N, List, []).

split_n(0, List, Acc) -> {lists:reverse(Acc), List};
split_n(_, [], Acc) -> {lists:reverse(Acc), []};
split_n(N, [H | T], Acc) -> split_n(N - 1, T, [H | Acc]).

十、总结 #

本章学习了:

  • 列表的本质和定义
  • 列表构造和操作
  • 列表模式匹配
  • lists模块函数
  • 递归处理列表
  • 列表推导式
  • 性能考虑
  • 实用函数

准备好学习元组类型了吗?让我们进入下一章。

最后更新:2026-03-27