# 2.4 针对列表类型变量的命令

## 2.4.1 读写列表的命令

* `LPUSH`:
  * 语法:`LPUSH key element [element ...]`
  * 功能:将1个或多个值依次插入列表头部.其中key指定待插入的列表,element表示插入到列表的值.返回值为插入操作后的列表长度.
* `LINDEX`:
  * 语法:`LINDEX key index`
  * 功能:读取列表的值.其中key指定待读取的列表,index指定列表值的索引号.注意索引号是从0开始的.若key或index不存在则返回nil.

例:

插入列表操作:

查看LIST:

```
127.0.0.1:6379> LRANGE 001 0 -1
(empty array)
```

可以看到,此时key为001的list是不存在的

向list的头部插入一个元素:

```
127.0.0.1:6379> LPUSH 001 "dataTeam"
(integer) 1
```

再向list的头部插入一个:

```
127.0.0.1:6379> LPUSH 001 15000
(integer) 2
```

再向list的头部插入一个:

```
127.0.0.1:6379> LPUSH 001 'Peter'
(integer) 3
```

查看list中索引为0的元素的值:

```
127.0.0.1:6379> LINDEX 001 0
"Peter"
```

查看list中索引为1的元素的值:

```
127.0.0.1:6379> LINDEX 001 1
"15000"
```

查看list中索引为2的元素的值:

```
127.0.0.1:6379> LINDEX 001 2
"dataTeam"
```

`LINDEX`指令不指定索引则报错:

```
127.0.0.1:6379> LINDEX 001
(error) ERR wrong number of arguments for 'lindex' command
```

`LPUSH`指令一次设置多个元素:

```
127.0.0.1:6379> LPUSH 002 'dataTeam' 12000 'Mary'
(integer) 3
```

查看list中索引为1的元素的值:

```
127.0.0.1:6379> LINDEX 002 1
"12000"
```

* `RPUSH`:
  * 语法:`RPUSH key element [element ...]`
  * 功能:将1个或多个值依次插入到列表尾部.其中key指定待插入的列表,element表示插入到列表的值.返回值为插入操作后的列表长度.

例:

一次向list尾部插入多个元素:

```
127.0.0.1:6379> RPUSH 003 'Tim' 20000 'Hr Team'
(integer) 3
```

获取list中索引为0的元素的值:

```
127.0.0.1:6379> LINDEX 003 0
"Tim"
```

获取list中索引为1的元素的值:

```
127.0.0.1:6379> LINDEX 003 1
"20000"
```

获取list中索引为2的元素的值:

```
127.0.0.1:6379> LINDEX 003 2
"Hr Team"
```

获取list中不存在的索引:

```
127.0.0.1:6379> LINDEX 003 3
(nil)
```

## 2.4.2 lpushx和rpushx命令

* `LPUSHX`
  * 语法:`LPUSHX key element [element ...]`
  * 功能:仅当key存在时向头部插入数据.返回值为插入操作后的列表长度.可以认为返回0则表示插入操作没有执行.
* `RPUSHX`:
  * 语法:`RPUSHX key element [element ...]`
  * 功能:仅当key存在时向尾部插入数据.返回值为插入操作后的列表长度.可以认为返回0则表示插入操作没有执行.

例:

删除key为003的list:

```
127.0.0.1:6379> DEL 003
(integer) 1
```

当key存在时向头部插入:

```
127.0.0.1:6379> LPUSHX 003 'dataTeam'
(integer) 0
```

向头部插入:

```
127.0.0.1:6379> LPUSH 003 'dataTeam'
(integer) 1
```

当key存在时向头部插入:

```
127.0.0.1:6379> LPUSHX 003 10000
(integer) 2
```

查看索引为1的元素的值:

```
127.0.0.1:6379> LINDEX 003 1
"dataTeam"
```

删除key为004的list:

```
127.0.0.1:6379> DEL 004
(integer) 0
```

当key存在时向尾部插入:

```
127.0.0.1:6379> RPUSHX 004 'Tim'
(integer) 0
```

向尾部插入:

```
127.0.0.1:6379> RPUSH 004 'Tim'
(integer) 1
```

当key存在时向尾部插入:

```
127.0.0.1:6379> RPUSHX 004 15000
(integer) 2
```

查看索引为1的元素的值:

```
127.0.0.1:6379> LINDEX 004 1
"15000"
```

## 2.4.3 用list模拟堆栈和队列

* `LPOP`:
  * 语法:`LPOP key`
  * 功能:从list头部弹出元素.若list中没有元素,则返回nil
* `RPOP`:
  * 语法:`RPOP key`
  * 功能:从list尾部弹出元素.若list中没有元素,则返回nil

例:使用`LPUSH`和`LPOP`命令模拟一个栈:

模拟入栈:

```
127.0.0.1:6379> LPUSH myStack 1
(integer) 1
127.0.0.1:6379> LPUSH myStack 2
(integer) 2
127.0.0.1:6379> LPUSH myStack 3
(integer) 3
```

模拟出栈:

```
127.0.0.1:6379> LPOP myStack
"3"
127.0.0.1:6379> LPOP myStack
"2"
127.0.0.1:6379> LPOP myStack
"1"
```

可以看到,模拟了栈的先入后出的特性

对一个没有元素的list使用`LPOP`:

```
127.0.0.1:6379> LPOP myStack
(nil)
```

例:使用`LPUSH`和`RPOP`命令模拟一个队列:

模拟入队:

```
127.0.0.1:6379> LPUSH myQueue 1
(integer) 1
127.0.0.1:6379> LPUSH myQueue 2
(integer) 2
127.0.0.1:6379> LPUSH myQueue 3
(integer) 3
```

模拟出队:

```
127.0.0.1:6379> RPOP myQueue
"1"
127.0.0.1:6379> RPOP myQueue
"2"
127.0.0.1:6379> RPOP myQueue
"3"
```

可以看到,模拟了队列的先入先出的特性

对一个没有元素的list使用`RPOP`:

```
127.0.0.1:6379> RPOP myQueue
(nil)
```

## 2.4.4 用lrange命令获取指定区间内的数据

* `LRANGE`:
  * 语法:`LRANGE key start stop`
  * 功能:获取key对应的list中指定区间内的数据.其中:
    * start:开始的索引
    * stop:结束的索引
    * 包含start位置和stop位置的元素

例:

删除list:

```
127.0.0.1:6379> DEL 003
(integer) 1
```

从尾部插入3个元素:

```
127.0.0.1:6379> RPUSH 003 'dataTeam' 15000 'Mary'
(integer) 3
```

获取从第0个索引到第1个索引的元素:

```
127.0.0.1:6379> LRANGE 003 0 1
1) "dataTeam"
2) "15000"
```

获取从第0个索引到第2个索引的元素:

```
127.0.0.1:6379> LRANGE 003 0 2
1) "dataTeam"
2) "15000"
3) "Mary"
```

获取从第0个索引到第4个索引的元素:

```
127.0.0.1:6379> LRANGE 003 0 4
1) "dataTeam"
2) "15000"
3) "Mary"
```

可以看到,此时由于list中只有3个元素,故只返回了3个元素的值.

start的索引值大于stop的索引值时:

```
127.0.0.1:6379> LRANGE 003 4 0
(empty array)
```

可以看到,当start的索引值大于stop的索引值时,返回值为`empty array`

## 2.4.5 用lset命令修改列表数据

* `LSET`:
  * 语法:`LSET key index element`
  * 功能:将key对应的list中指定index位置上的元素修改为element.若指定的key不存在,则报错key不存在;若index在list中不存在,则报错索引越界.

例:

删除list:

```
127.0.0.1:6379> DEL 003
(integer) 1
```

从list尾部插入元素:

```
127.0.0.1:6379> RPUSH 003 "Mike" 15000
(integer) 2
```

查看索引为1的元素:

```
127.0.0.1:6379> LINDEX 003 1
"15000"
```

修改索引为1的元素值:

```
127.0.0.1:6379> LSET 003 1 18000
OK
```

查看修改结果:

```
127.0.0.1:6379> LINDEX 003 1
"18000"
```

查看键名为003的List中的所有元素:

```
127.0.0.1:6379> LRANGE 003 0 -1
1) "Mike"
2) "18000"
```

可以看到,此时List中仅有2个元素

对List中一个不存在的索引修改元素值:

```
127.0.0.1:6379> LSET 003 5 20000
(error) ERR index out of range
```

可以看到,报错索引越界

对一个不存在的List修改其索引对应的元素值:

```
127.0.0.1:6379> LSET 005 1 12000
(error) ERR no such key
```

可以看到,对一个不存在的List修改其索引对应的元素值将报错key不存在

## 2.4.6 删除列表数据的命令

* `LPOP`
  * 语法:`LPOP key [count]`
  * 功能:返回并删除key对应的List头部的前count个元素.若list中没有元素或key对应的list不存在,则返回nil
* `RPOP`
  * 语法: `RPOP key [count]`
  * 功能:返回并删除key对应的List尾部的后count个元素.若list中没有元素或key对应的list不存在,则返回nil

例:

删除key对应的list:

```
127.0.0.1:6379> DEL 003
(integer) 1
```

从list尾部插入元素:

```
127.0.0.1:6379> RPUSH 003 "Mike" 15000 "dataTeam" "male"
(integer) 4
```

删除list头部的2个元素:

```
127.0.0.1:6379> LPOP 003 2
1) "Mike"
2) "15000"
```

查看删除后的结果:

```
127.0.0.1:6379> LRANGE 003 0 -1
1) "dataTeam"
2) "male"
```

删除list尾部的元素:

```
127.0.0.1:6379> RPOP 003
"male"
127.0.0.1:6379> RPOP 003
"dataTeam"
```

```
127.0.0.1:6379> RPOP 003
(nil)
```

可以看到,当list中没有元素时,执行删除操作的返回值为nil

查看删除后的结果:

```
127.0.0.1:6379> LRANGE 003 0 -1
1) "dataTeam"
```

对一个不存在的key使用删除元素操作:

```
127.0.0.1:6379> DEL 010
(integer) 0
```

```
127.0.0.1:6379> LPOP 010
(nil)
127.0.0.1:6379> RPOP 010 2
(nil)
```

可以看到,对一个不存在的key使用删除元素操作时,将返回nil

* `LREM`
  * 语法:`LREM key count element`.其中:
    * key:指向待删除的list
    * count:
      * `count > 0`时:从头到尾方向删除,删除数量为count个、值为element的元素
      * `count < 0`时:从尾到头方向删除,删除数量为count个、值为element的元素
      * `count = 0`时:删除列表中所有值为element的元素

例:

删除list:

```
127.0.0.1:6379> DEL 001
(integer) 1
```

创建list:

```
127.0.0.1:6379> LPUSH 001 1 1 2 2 1
(integer) 5
```

删除list中所有值为1的元素:

```
127.0.0.1:6379> LREM 001 0 1
(integer) 3
```

查看删除元素后的list:

```
127.0.0.1:6379> LRANGE 001 0 -1
1) "2"
2) "2"
```

删除并重新创建list:

```
127.0.0.1:6379> DEL 001
(integer) 1
127.0.0.1:6379> LPUSH 001 1 1 2 2 1
(integer) 5
```

从头到尾方向删除2个值为1的元素:

```
127.0.0.1:6379> LREM 001 2 1
(integer) 2
```

查看删除结果:

```
127.0.0.1:6379> LRANGE 001 0 -1
1) "2"
2) "2"
3) "1"
```

删除并重新创建list:

```
127.0.0.1:6379> DEL 001
(integer) 1
127.0.0.1:6379> LPUSH 001 1 1 2 2 1
(integer) 5
```

从尾到头方向删除2个值为1的元素:

```
127.0.0.1:6379> LREM 001 -2 1
(integer) 2
```

查看删除结果:

```
127.0.0.1:6379> LRANGE 001 0 -1
1) "1"
2) "2"
3) "2"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://redis.sai.show/di-2-zhang-shi-jian-redis-de-ji-ben-shu-ju-lei-xing/2.4-zhen-dui-lie-biao-lei-xing-bian-liang-de-ming-ling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
