Is it good style to use tuples rather than lists for module-level constant iterables in Python? For example, I have a list of important strings at the top of my file that I need to look for in my input:
IMPORTANT_STRINGS = [
"Hello world!",
"Goodbye world!",
"Foo...",
# etc --- there are about 40 entries
]
IMPORTANT_STRINGS
will never be modified while my program is running.
On the one hand, I think that immutability is good and that I should prefer immutable data structures whenever possible, so I should use a tuple instead.
On the other hand, I think that tuples are more than just immutable lists: they're for heterogenous collections that should be used when you're passing around things like pairs, triples, etc --- fixed-size things whose size is important to what they are. I also don't think that I've ever seen Python code in the wild that uses tuples for constants like this, and it looks really strange to my eye to say:
IMPORTANT_STRINGS = (
"Hello world!",
etc
)
Create a module, call it foo.py and insert the following:
FOO = 'a', 'b'
BAR = ['a', 'b']
Now import them and see how they respond to in-place operations:
>>> import foo
>>> from foo import FOO, BAR
>>> FOO += 'c', 'd'
>>> BAR += 'c', 'd'
>>> FOO
('a', 'b', 'c', 'd')
>>> foo.FOO
('a', 'b')
>>> foo.BAR
['a', 'b', 'c', 'd']
As we can see, FOO
, the tuple, remains in its original state as the canonical collection in the foo
module. BAR
on the other hand, can be mutated.
Which should you prefer?
It depends on what you want to happen when other modules access the collection. In many cases, we want other modules to be able to add to a canonical list. In some cases, we don't. The answer is to do what is appropriate given your circumstances and purposes and intentions for design and use.
In your case, you say:
IMPORTANT STRINGS will never be modified while my program is running.
If they never should be modified, then tuples are fine. If you want your code to be useful to others who may need to share data in the same process, then you should go with a list.
You mention:
I think that tuples are more than just immutable lists: they're for heterogenous collections that should be used when you're passing around things like pairs, triples, etc --- fixed-size things whose size is important to what they are.
Tuples are essentially immutable lists, and lists can have all kinds of objects in them too. Yes, fixed size, but that's really just a direct result from the immutability.
Should you use tuples as immutable lists? I wouldn't. I would use lists on the theory that users of my code are responsible, and can handle modifying lists from modules they didn't write.
Note that the ability of lists to be extended with tuples as demonstrated above means that you can generally start with tuples and then move to lists as needed.
I'd go for the tuple. Tuples are faster, immutable and - cause of this - more secure. Why do you want a mutable type for something that should be immutable?
The argument that "tuples are for heterogenous collections" has no sense to me. Lists can store heterogenous elements too. The assumption that tuples = heterogeneous and lists = homogeneous is just a generalization, usually you want a list to iterate through elements and work with them similarly (If not exactly in the same way at least in a polymorphic way)
Tuples on the other hand are slightly similar to a struct in the sense that are used to store values that have some relation in the model you're coding and in this way are related to heterogeneous elements, but why can't them be the same type? For example a 3 dimensional vector would be represented as a tuple (At least is the most intuitive way) but it's composed just by 3 numbers, should we use a list just cause they're the same?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With