---
source_url: https://docs.dolphindb.cn/zh/progr/data_types_forms/TupleANYVector.html
fetched_at: 2026-05-19T09:00:32Z
category: progr
title: 元组 (tuple)
sha1: 57959cebb7b0d93e4cd9598fd447940af8471a30
---

# 元组 (tuple)

向量按存储的数据类型可以分为元组和强类型向量。强类型向量要求所有元素是具有相同的数据类型的标量，因此强类型向量具有明确的数据类型。而元组的存储对象可以是标量或向量，其类型可以相同或不同，因此元组没有明确的数据类型，DolphinDB
定义元组的数据类型为 ANY。

元组的声明符号是圆括号，如："(1, 2, 3)"。用方括号声明强类型向量时，若其中包含不同的数据类型或包含向量，系统会自动将其转换为一个元组，如："[1,
'A']"，"[[1,2,3], [4,5]]"。在本章后面将会提到，可以使用方括号来构造元组。

## 创建元组

(1) 圆括号内用逗号分隔定义。使用这种方式，无论元素的类型是否相同，一定会生成一个元组。元组内的元素可以跨行书写。

```dolphindb
a=(1 2 3, `IBM`MSFT`GOOG, 2.5);
a;
// output: ([1,2,3],["IBM","MSFT","GOOG"],2.5)

// 也可跨行书写式
a=(1 2 3, 
`IBM`MSFT`GOOG, 2.5);
a;
// output: ([1,2,3],["IBM","MSFT","GOOG"],2.5)

a=(1, 2, 3);
typestr a;
// output: ANY VECTOR

x=(1..10, `GOOG);
x;
// output: ([1,2,3,4,5,6,7,8,9,10],"GOOG")

x=1..10;
y=rand(100,10);
a=(x+y,x-y);
a;
// output: ([73,26,32,96,26,86,11,63,21,49],[-71,-22,-26,-88,-16,-74,3,-47,-3,-29])
```

可以用()来生成一个空的元组。

```dolphindb
x=();
x.append!(1..3);
// output: ([1,2,3])
x.append!(`GS);
// output: ([1,2,3],"GS")

x=(1,2,3);
x;
// output: (1,2,3)
x.append!(`GS);
// output: (1,2,3,"GS")
```

不可使用 *append!* 函数将强类型向量转换为元组。

```dolphindb
x=1 2 3;
x;
// output: [1,2,3]
x.append!(`GS);
// output: Incompatible type. Expected: INT, Actual: STRING
```

(2) 用空格分隔不同类型的数据，或者在方括号内使用逗号分隔不同类型的数据。方括号 "[]" 首先会尝试创建一个强类型向量。如果不成功，则会创建一个元组。

```dolphindb
a = 3 2012.02.03 `GOOG;
// output: (3,2012.02.03,"GOOG")
typestr a;
// output: ANY VECTOR

a=[[1,2,3,4,5,6,7,8,9,10],2,[`IBM, `MSFT,`GOOG]];
a;
// output: ([1,2,3,4,5,6,7,8,9,10],2,["IBM","MSFT","GOOG"])

x=1..10;
y=rand(100,10);
b=[x+y,x-y];
b;
// output: ([73,26,32,96,26,86,11,63,21,49],[-71,-22,-26,-88,-16,-74,3,-47,-3,-29])
```

(3) 使用函数 [array](../../funcs/a/array.html) 将第一个输入变量设为 ANY，然后定义每个元素。

```dolphindb
a=array(ANY, 3);
a[0]=1..10;
a[1]=2;
a[2]=`IBM`MSFT`GOOG;
a;
// output: ([1,2,3,4,5,6,7,8,9,10],2,["IBM","MSFT","GOOG"])
```

## 访问元组

```dolphindb
x=(1 2 3 4 5 6 7 8 9 10,(5 7 8, 11 3 5));
x;
// output: ([1,2,3,4,5,6,7,8,9,10],([5,7,8],[11,3,5]))

x[1];
// output: ([5,7,8],[11,3,5])

x[1,1];
// output: [11,3,5]

x[1,1,1];
// output: 3

x[0 1];
// output: ([1,2,3,4,5,6,7,8,9,10],([5,7,8],[11,3,5]))

x[0 1,1];
// output: (2,[11,3,5])

x[, 1];
// output: (2,[11,3,5])

x[1, ,0 2];
// output: ([5,8],[11,5])

x[,1,1];
// output: (2,3)

x[1 2];
// output: (([5,7,8],[11,3,5]),)
```

## 修改元组

我们可以向一个元组中添加新元素，也可将新的对象赋值给元组里的元素。

1. 向一个元组中添加新元素。

   ```dolphindb
   x=`C 120`BH 100;
   x;
   // output: ("C",120,"BH",100)

   x.append!("AAPL");
   // output: ("C",120,"BH",100,"AAPL")

   x.append!(300);
   // output: ("C",120,"BH",100,"AAPL",300)

   x.append!(`IBM 600);
   // output: ("C",120,"BH",100,"AAPL",300,("IBM",600))
   ```
2. 通过将新的对象赋值给元组里的元素来修改元素值。

   ```dolphindb
   tp = [["aaaa", "ccccccc"], ["dddd"]]
   //将元组 tp 的第一个元素赋值给对象 a 
   a = tp[0]
   //修改对象 a 的第2个元素值
   a[1] = "A"
   a;
   // output: ["aaaa","A"]
   //通过将对象 a 赋值给 tp[0]，来修改 tp 里的第一个元素值
   tp[0] = a
   tp
   // output: (["aaaa","A"],["dddd"])
   ```

## 涉及元组的计算

元组是用来容纳不同的数据类型，而不是为了高效的计算。如果元组的元素都是数字，且所有元素是标量或等长向量，仍可使用元组进行计算。

支持元组的函数包括常规标量函数、向量函数（常规及 cum/m 系列）、聚合函数。

- 对于非向量函数，始终按行操作字典：即将把每个元素对应位置的值组成一行，再逐行应用函数。
- 对于向量函数，元组的计算方式可按行或按列执行，由配置项 *processVectorFunctionOverTupleByRow*
  控制：

  - true（默认）：按行操作，即将把每个元素对应位置的值组成一行，再逐行应用函数。
  - false：按列操作，即每个元素视为一列，函数分别作用于各列。

```dolphindb
a=(2, [3, 5], 10);
max a;
// output: [10,10]

prod a;
// output: [60,100]

cumsum a;
// output: (2,[5,7],[15,17])
```

我们可以将逻辑或关系运算符应用于元组。

```dolphindb
a=(2, [3, 5], 10);
a>3;
// output: (0,[0,1],1)

a==2;
// output: (1,[0,0],0)

isNull a;
// output: (0,[0,0],0)
```

我们可以对元组使用某些运算符，比如：[add](https://docs.dolphindb.cn/zh/funcs/a/add.html)、[sub](https://docs.dolphindb.cn/zh/funcs/s/sub.html)、[mul](https://docs.dolphindb.cn/zh/funcs/m/mul.html)、[div](https://docs.dolphindb.cn/zh/funcs/d/div.html)、[ratio](https://docs.dolphindb.cn/zh/funcs/r/ratio.html)、[mod](https://docs.dolphindb.cn/zh/funcs/m/mod.html)、[pow](https://docs.dolphindb.cn/zh/funcs/p/pow.html)、[abs](https://docs.dolphindb.cn/zh/funcs/a/abs.html)。

```dolphindb
a=(2, [3, 5], 10);
a+2;
// output: (4,[5,7],12)

a pow 3;
// output: (8,[27,125],1000)
```

## 对多个元素赋值

```dolphindb
x,y=(1 2 3, 2:5);
x;
// output: [1,2,3]
y;
// output: 2 : 5
```

## 元组用于函数返回值，返回多个值

```dolphindb
def foo(a,b){return a+b, a-b};
x = foo(15,10);
x;
// output: (25,5)

typestr x;
// output: ANY VECTOR
```

## 特殊使用场景

实质上，元组的每个元素存储的是对象的地址。当在元组上应用 [take](../../funcs/t/take.html) 函数进行循环取值生成一个新的元组时，新元组实际拷贝的是原元组各个元素的地址（引用），而非实际的元素值，即进行的是浅拷贝（shallow
copy）。

在某些特殊场景下，如更新字典：字典的 value 是通过对一个元组应用 take 函数生成的元组，多个元素实际上指向了同一个对象。此时对某个 key 对应的 value
进行追加，可能会导致其他 key 对应的 value 发生改变。

下例对 key=1 追加一个元素 0，可以发现 key=4 的值也发生了改变：

```dolphindb
t = [[1,2],[2,3],[3]]
d = dict(take(0..10,5),take(t, 5))
d;
/* output: 
0->[1,2]
1->[2,3]
2->[3]
3->[1,2]
4->[2,3]
*/

d.dictUpdate!(append!,1,0)
d;

/* output: 
0->[1,2]
1->[2,3,0]
2->[3]
3->[1,2]
4->[2,3,0]
*/

t = [[1,2],[2,3],[3]]
d = dict(take(0..10,5),[[1,2],[2,3],[3],[1,2],[2,3]])
d;

/* output: 
0->[1,2]
1->[2,3]
2->[3]
3->[1,2]
4->[2,3]
*/

d.dictUpdate!(append!,1,0)
d;

/* output: 
0->[1,2]
1->[2,3,0]
2->[3]
3->[1,2]
4->[2,3]
*/
```
