How to create a tuple of an empty tuple in Python? - python

How can I create a tuple consisting of just an empty tuple, i.e. (())? I have tried tuple(tuple()), tuple(tuple(tuple())), tuple([]) and tuple(tuple([])) which all gave me ().
The reason that I use such a thing is as follows: Assume you have n bags with m items. To represent a list of items in a bag, I use a tuple of length n where each element of that tuple is a representative for a bag. A bag might be empty, which is labeled by (). Now, at some initial point, I have just one bag with empty items!

The empty tuple is () (or the more-verbose and slower tuple()), and a tuple with just one item (such as the integer 1), called a singleton (see here and here) is (1,). Therefore, the tuple containing only the empty tuple is
((),)
Here are some results showing that works:
>>> a=((),)
>>> type(a)
<type 'tuple'>
>>> len(a)
1
>>> a[0]
()
>>> type(a[0])
<type 'tuple'>
>>> len(a[0])
0

I'm not surprised this (()) didn't work, since the outer parentheses get interpreted as that - parentheses. So (()) == (), just like (2) == 2. This should work, however:
((),)

An empty tuple:
my_tuple = ()
A tuple with 1 string:
my_tuple = ('foo',)
A tuple with 2 strings:
my_tuple = ('foo', 'bar')
A tuple with 1 empty tuple:
my_tuple = ((),)
A tuple with 2 empty tuples:
my_tuple = ((), ())

in Python 2, tuple() is the only genuine empty tuple, but (), and ((),) create a tuple of length 1 that contains a tuple of length 0 - but not a tuple of length zero itself.
If you want an answer to "how do I create an empty (or zero length) tuple.... I found this post with the search "how to create an empty tuple", then realized this was not the same question, but could be mistaken for that question (as the search does), so I though I would provide the answer to :
How do you simply create an empty tuple?
the original question could mislead you, as the original answers are almost good enough as an empty tuple, but do fail one test.
(), will create an 'empty' tuple as suggested in previous answers with ((),) which will also work, as will ((( ((( (),))) ))) in fact you can use any number of outer brackets you choose, they just work as brackets. However, python, when printing a tuple, does add one set of outer brackets.
empty brackets is a non-standard representation of 'no value' and adding the trailing comma makes a tuple from 'no value'. But it is a tuple with a 'no value' entry, not an empty tuple.
Note: This is not a zero length tuple, as the other examples have also shown. The outer tuple is a tuple with one value, just that value has itself, is the empty tuple. So this creates an empty tuple inside another tuple, and the other tuple is not empty. For a true empty tuple by itself, use tuple() although the (), behaves some what similar, it is not quite correct.
>>> a = (),
>>> type(a)
<class 'tuple'>
>>> len(a)
1
>>> a
((),)
>>> len(a[0]) # the inside tuple is empty, just not the outside one
0
Similarly, for a tuple of length 1 but with a value (of zero in the case of b, and "" for the example with c)
>>> b = 0,
>>> type(b)
<class 'tuple'>
>>> len(b)
1
>>>b
(0,)
# now with an empty string
>>> c = "",
>>> type(c)
<class 'tuple'>
>>> len(c)
1
>>>c
('',)
>>> len (c[0]) # same len of c[0] as with 'empty' tuple
0
So the outer brackets are included for displaying a tuple, but not actually part of the tuple, nor needed for creating the tuple.
However all these brackets methods are not a real empty at the outer level, which is something that also has use cases.
>>> a = ((),) # extra brackets just to show same as other answers
>>> len(a)
1
>>> if a:
print("not empty")
not empty
>>> e = tuple()
>>> len(e)
0
>>> type(e)
<class 'tuple'>
>>> if e:
print("not empty")
>>> # note...did not print...so e acts as false as an empty tuple should
So if you really need a genuine empty tuple, use tuple(), but if near enough is all you need, you can use (), or ((),)

In the general case, it's the commas that make tuples, not the parentheses. Things become confusing in the case of empty tuples because a standalone comma is syntactically incorrect. So for the special case of an empty tuple, the "it is commas that make tuples" rule does not apply, and the special case () syntax is used instead.

Related

python: comparing list of tuple

Just wondering the following:
print [()] == list(tuple()) # prints False
The first is a list containing an empty tuple, the second is an empty list.
Why this code prints False instead of True (same result in python 2 and 3)?
Thanks in advance!
You compared a list with one element (an empty tuple) with an empty list. list(tuple()) does not do what you think it does.
That's because list(object) does not produce a list with that one object as an element. list() converts the object, which must be iterable, to a list. It copies the elements out of the object:
>>> dictionary = {'foo': 'bar'}
>>> list(dictionary) # iteration over a dictionary produces keys
['foo']
You gave it an empty tuple, so the result is an empty list:
>>> empty = ()
>>> list(empty)
[]
tuple() does the same thing, by the way. And both list() and tuple() without an argument produce an empty object.

Differentiating a tuple from a tuple of tuples

I have a tuple, and a tuple of tuples.
import numpy as np
a = ("Control", "Group1")
b = (("Control", "Group1"), ("Control", "Group1", "Group2))
How can I tell that a is fundamentally different from b? Both
print(len(a))
print(np.shape(a))
print(len(np.shape(a)))
and
print(len(b))
print(np.shape(b))
print(len(np.shape(b)))
produce the same output:
2
(2,)
1
Thanks in advance again!
You cannot, because they are not fundamentally different.
What should happen for the following?
c = (("Foo", "bar"), "baz")
It’s also a tuple, and it contains both "bare" values as well as another tuple.
If you need to detect tuples which only consist of tuples, use:
if all(isinstance(element, tuple) for element in a)
If you need to detect tuples which only consist of non-tuples, use:
if not any(isinstance(element, tuple) for element in a)
Both of the above are have a time complexity of O(n) (with n being the number of elements in a), which may not be desirable depending from where your data is coming. It is however unavoidable, unless you are willing to take the risk not actually having tuples of tuples.
Depending on what you’re doing with your data, you might actually want to check for a sequence of sequences. In that case, you should use the Sequence ABC (Python 2):
import collections.abc
if all(isinstance(element, collections.abc.Sequence) for element in a)
Use the equality operator, ==:
>>> a = ("Control", "Group1")
>>> b = (("Control", "Group1"), ("Control", "Group1", "Group2"))
>>> a == b
False
If you just want a vague idea of the general structure, and the string elements won't contain parentheses, you can count the parentheses:
>>> str(a).count('(')
1
>>> str(b).count('(')
3

little subtle difference with the filter() function

I was reading the filter() doc at http://docs.python.org/2/library/functions.html. I don't quite get the subtle differences of the results produced by the filter() function shown below. I tried to make the p & q lists as similar as possible to enhance this subtle differences.
>>> p = ("A", "e", "I", "o", "U", "o")
>>> filter(lambda x: x not in ["e", "o"], p)
('A', 'I', 'U')
>>> q = ("Z", "o")
>>> filter(lambda x: x not in ["e", "o"], q)
('Z',)
Can someone explain this to me?
It is because the ('Z',) is a tuple and ('Z') is simply a string enclosed in Parenthesis.
print type(('Z',))
# <type 'tuple'>
print type(('Z'))
# <type 'str'>
When you say ('Z'), Python considers it something similar to (1 + 2). It simply evaluates the expression inside that.
But when you put a comma inside that ('Z',) it considers that as a tuple.
Quoting from the docs,
A parenthesized expression list yields whatever that expression list
yields: if the list contains at least one comma, it yields a tuple;
otherwise, it yields the single expression that makes up the
expression list.
An empty pair of parentheses yields an empty tuple object. Since
tuples are immutable, the rules for literals apply (i.e., two
occurrences of the empty tuple may or may not yield the same object).
Note that tuples are not formed by the parentheses, but rather by use
of the comma operator. The exception is the empty tuple, for which
parentheses are required — allowing unparenthesized “nothing” in
expressions would cause ambiguities and allow common typos to pass
uncaught.
As the property of tuples,
>>> ('a','b',) == ('a','b')
True
>>> ('a',) == ('a')
False
>>> ('a') in ('a',)
True
both the type of first and second filters that you specified(not in mine) are same as ('a','b') and ('a',) are tuples and hence ('a') is not a tuple and just str
>>> type(('a','b',))
<type 'tuple'>
>>> type(('a','b'))
<type 'tuple'>
>>> type(('a',))
<type 'tuple'>
>>> type(('a'))
<type 'str'>

Difference accessing element(s) of tuple and list

Why is there this difference accessing the element(s) of t when making it a tuple?
>>> t = [('ID','int')]
>>> for r in t:
print r
('ID', 'int')
t = (('ID','int'))
>>> for r in t:
print r
ID
int
I'd expect this to be exactly the same as the first example! Whereas populating the tuple with more than one element the behavior changes.
>>> t = (('ID','int'),('DEF','str'))
>>> for r in t:
print r
('ID', 'int')
('DEF', 'str')
>>> t = [('ID','int'),('DEF','str')]
>>> for r in t:
print r
('ID', 'int')
('DEF', 'str')
Can somebody give a short explanation? I'm running python 2.7
(('a', 'b')) is the same as ('a', 'b').
You actually want (('a', 'b'),)
This is documented here:
5.13. Expression lists
expression_list ::= expression ( "," expression )* [","]
An expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.
The trailing comma is required only to create a single tuple (a.k.a. a singleton); it is optional in all other cases. A single expression without a trailing comma doesn’t create a tuple, but rather yields the value of that expression. (To create an empty tuple, use an empty pair of parentheses: ().)
Remember, that without this restriction, should the expression (3) * (4) be the multiplication of two numbers, or two tuples? Most users would expect that to be the multiplication of numbers.
t = [('ID','int')]
is a tuple in a list.
t = (('ID','int'))
is a tuple with brackets around it.
t = ('ID','int'),
is a tuple in a tuple.
The , makes the tuple! The brackets around a tuple are only needed to avoid ambiguity.

Why is a[:]=1 fundamentally different to a[:]='1'?

Please consider the two snippets of code (notice the distinction between string and integer):
a = []
a[:] = '1'
and
a = []
a[:] = 1
In the first case a is ['1']. In the second, I get the error TypeError: can only assign an iterable. Why would using '1' over 1 be fundamentally different here?
Assigning to a slice requires an iterable on the right-hand side.
'1' is iterable, while 1 is not. Consider the following:
In [7]: a=[]
In [8]: a[:]='abc'
The result is:
In [9]: a
Out[9]: ['a', 'b', 'c']
As you can see, the list gets each character of the string as a separate item. This is a consequence of the fact that iterating over a string yields its characters.
If you want to replace a range of a's elements with a single scalar, simply wrap the scalar in an iterable of some sort:
In [11]: a[:]=(1,) # single-element tuple
In [12]: a
Out[12]: [1]
This also applies to strings (provided the string is to be treated as a single item and not as a sequence of characters):
In [17]: a[:]=('abc',)
In [18]: a
Out[18]: ['abc']
'1' is a string, but it is iterable. It is like a list of characters. a[:]='1' replaces the contents of the list a with the content of the string '1'. But 1 is an integer.
Python does not change the type.
Example:
print bool(1=='1') # --> False

Categories