I had a tuple of integers from a config file and a NumPy function that expected an array. The conversion was a one-liner, but I wanted to be deliberate about which one I called.
Tuple, list, array module, NumPy. Each is a different type with a different cost, and the answer changes the downstream code. The exact path you take depends on what you are about to do with the result.
Below are the four ways I reach for, when each one is the right pick, and the small gotchas I have hit with each.
The four ways to convert a tuple in Python
All four of the methods below produce something iterable from a tuple. The differences are type, mutability, and per-element cost. Pick by the next operation, not by the conversion itself.
| Method | Result type | Mutates? | Best for |
|---|---|---|---|
| array.array(typecode, tup) | array.array | Yes | Tight loops, C-style buffer, fixed numeric type |
| np.array(tup) | numpy.ndarray | Yes | Vectorised math, broadcasting, dtype control |
| list(tup) | list | Yes | General purpose, mixed types, append/pop later |
| np.asarray(tup) | numpy.ndarray | No copy if already ndarray | Functions that may receive either tuple or array |
Two of these come from the standard library and need no install. The two NumPy ones are interchangeable for a plain tuple, but asarray is cheaper when the input might already be an array.
Use the array module for compact numeric buffers
The array module ships with Python. It produces a homogeneous buffer that takes less memory than a list of Python ints and plays well with C extensions that expect a typed array.
You need a typecode. ‘i’ is signed int, ‘d’ is double, ‘f’ is float, ‘u’ is unicode character. The typecode constrains what you can put in.
import array
tup = (23, 98, 3, -2, -4, 11)
buf = array.array('i', tup)
print(buf)
print(type(buf).__name__)
Output:
array('i', [23, 98, 3, -2, -4, 11])
array
Try to push a string into that array and Python refuses:
buf.append('hello')
# TypeError: an integer is required (got type str)
That refusal is the feature. A list will accept anything, an array will not, and the failure happens at the right time.
Use NumPy when you want vectorised math
NumPy gives you a proper ndarray with a dtype, broadcasting, and the whole ecosystem of ufuncs. Install with pip install numpy if you do not have it.
import numpy as np
tup = (23, 98, 3, -2, -4, 11)
arr = np.array(tup)
print(arr)
print(arr.dtype, type(arr).__name__)
Output:
[ 23 98 3 -2 -4 11]
int64 ndarray
For pure integer tuples the default dtype is int64. If your tuple has floats, NumPy picks float64. You can force a dtype and downcast on the way in:
small = np.array(tup, dtype=np.int8)
print(small.dtype, small.nbytes)
# int8 7
For a generator or other non-sequence iterable, np.fromiter is the right entry point. It walks the iterable once and produces an array without buffering the whole thing in a list first.
arr = np.fromiter(tup, dtype=np.int32)
print(arr)
# [ 23 98 3 -2 -4 11]
If you are writing a function that may receive a tuple or an array, np.asarray is the lazy choice. It returns the input as-is when it is already an ndarray, and copies only when it has to.
def to_vec(x):
return np.asarray(x, dtype=np.int32)
print(to_vec(tup) is to_vec(to_vec(tup))) # False, tuple is not ndarray
print(to_vec(np.array(tup)) is to_vec(np.array(tup))) # True on second call, no copy
Use list() for mixed-type data and appends
If the result will hold strings, dicts, or a mix, drop the typed-array pretence and use list(). The conversion is the same shape, the result is the data structure every Python library accepts.
mixed = (1, 'two', 3.0, [4])
out = list(mixed)
print(out)
out.append({'k': 'v'})
print(out)
Output:
[1, 'two', 3.0, [4]]
[1, 'two', 3.0, [4], {'k': 'v'}]
list(tup) is the one conversion you cannot get wrong. It costs an allocation and one walk, both cheap.
That cost is per-element, so a 10 million-element tuple is going to take a moment. For that scale, the array module or NumPy is the right pick.
Common pitfalls
Three things trip people up the first time. None of them are bugs, but the error message can mislead you into looking in the wrong place.
- np.array on a tuple of mixed numbers and strings upcasts every element to a string. If your tuple contains a single stray str, the whole array is now dtype ‘
- array.array fails on the first wrong-type element with a TypeError that names the bad element, not the index. The line number in the traceback points to the constructor, not your tuple. Print the tuple and inspect the types yourself.
- np.asarray returns the input unchanged when it is already an ndarray, including its dtype. If you call asarray(x, dtype=np.float32) on a pre-existing int64 array, you get a copy with float32. If you do not pin the dtype, the input dtype wins.
Which one to use
The list is the only safe pick when types are mixed. NumPy is the right pick when the next step is a ufunc, a dot product, a reshape, or a save to .npy. The array module is the right pick when you want a typed buffer without pulling in NumPy.
Pick by the next operation, and the conversion is a one-liner either way.
Frequently asked questions
Is there a difference between np.array(tuple) and np.asarray(tuple) for a tuple input?
No, both produce a new array. They diverge when the input is already an ndarray. asarray returns it unchanged, array always copies.
Can I convert a tuple of strings to a NumPy array?
Yes. NumPy will pick a unicode dtype. Use dtype=object if you want to keep the original str objects without copying, or pass a structured dtype for fixed-width records.
Why does array.array fail when I try to add a float to an int array?
The typecode constrains element types. ‘i’ accepts signed int only. Use ‘d’ for double, ‘f’ for float, or build a new array with the right typecode.

