Difference accessing element(s) of tuple and list - python

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.

Related

Why is comma used while extending tuple by using asterisk in python? [duplicate]

This question already has answers here:
Why does adding a trailing comma after an expression create a tuple?
(6 answers)
Closed 3 years ago.
In the below code if I don't use comma then only one 0 gets printed while if I use comma 0 gets printed five times, why? Is it something to do with the immutable trait of the tuple?
food = (0,) * 5 # comma used
print (*food)
Output: 0 0 0 0 0
food = (0) * 5 # comma not used
print (*food)
Output:0
It's a syntax thing. What defines the tuple is not the parenthesis, but the presence of the comma:
Parenthesis around a single scalar expression are used to define order of evaluation: (1 + 2) * 3
A sequence of expressions separated by commas defines a tuple: 1, 2, 3.
This sequence can then be parenthesized if it needs to be embedded in some other expression: (1, 2, 3) * 5 is "the tuple (1,2,3) repeated five times".
Specifically for a single-item tuple, the syntax requires a trailing comma to differentiate it from a parenthesized expression: 0, is a tuple containing only the element 0; Usually you'd immediately want to parenthesize this expression if you wanted to embed it in a larger expression, e.g. (0,) * 5 ("the tuple consisting of zero, multiplied five times"). Whereas 0 and (0) both mean "the integer zero" (parenthesized in the latter form).
>>> type( (0, ) )
tuple
>>> type ( (0) )
int
So (0) * 5 is "the integer 0 multiplied by 5", giving you 0. There's no tuple involved at any point because the syntax you used does not define a tuple.
Because:
>>> (0)
0
>>>
So 0 * 5 is 0, while:
>>> (0,)
(0,)
>>>
Keeps it's type of a tuple.
Tuples and Sequences From documentation a tuple with one item is constructed by following a value with a comma
A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For Example
>>> t=('hello')
>>> t
'hello'
>>> type(t)
<class 'str'>
>>> t1=('hello',)
>>> t1
('hello',)
>>> type(t1)
<class 'tuple'>
>>>
According to: [Python 3.Docs]: Built-in Types - class tuple([iterable]) (emphasis is mine):
Using a trailing comma for a singleton tuple: a, or (a,)
food definition (note that things would be the same without parentheses):
In the 1st case, it's a tuple (as (0,) is a tuple)
In the the 2nd case, it's a plain int (0 * 5)
>>> v0 = (0,)
>>> v1 = (0)
>>>
>>> v0, type(v0)
((0,), <class 'tuple'>)
>>> v1, type(v1)
(0, <class 'int'>)
>>>
>>> v0 * 5
(0, 0, 0, 0, 0)
>>> v1 * 5
0
Are you absolutely sure that print(*food) works (as you claim it does) in the 2nd case?

How to create a tuple of an empty tuple in 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.

Why are tuples enclosed in parentheses?

a tuple is a comma-separated list of values
so the valid syntax to declare a tuple is:
tup = 'a', 'b', 'c', 'd'
But what I often see is a declaration like this:
tup = ('a', 'b', 'c', 'd')
What is the benefit of enclosing tuples in parentheses ?
From the Python docs:
... so that nested tuples are interpreted correctly. Tuples may be
input with or without surrounding parentheses, although often
parentheses are necessary anyway (if the tuple is part of a larger
expression).
Example of nested tuples:
tuple = ('a', ('b', 'c'), 'd')
The parentheses are just parentheses - they work by changing precedence. The only exception is if nothing is enclosed (ie ()) in which case it will generate an empty tuple.
The reason one would use parentheses nevertheless is that it will result in a fairly consistent notation. You can write the empty tuple and any other tuple that way.
Another reason is that one normally want a literal to have higher precedence than other operations. For example adding two tuples would be written (1,2)+(3,4) (if you omit the parentheses here you get 1,2+3,4 which means to add 2 and 3 first then form the tuple - the result is 1,5,4). Similar situations is when you want to pass a tuple to a function f(1,2) means to send the arguments 1 and 2 while f((1,2)) means to send the tuple (1,2). Yet another is if you want to include a tuple inside a tuple ((1,2),(3,4) and (1,2,3,4) are two different things.
Those are good answers! Here's just an additional example of tuples in action (packing/unpacking):
If you do this
x, y = y, x
what's happening is:
tuple_1 = (y, x)
(x, y) = tuple_1
which is the same as:
tuple_1 = (y, x)
x = tuple_1[0]
y = tuple_1[1]
In all these cases the parenthesis don't do anything at all to the python. But they are helpful if you want to say to someone reading the script "hey! I am making a tuple here! If you didn't see the comma I'll add these parenthesis to catch your eye!"
Of course the answers about nested tuples are correct. If you want to put a tuple inside something like a tuple or list...
A = x, (x, y) # same as (x, (x, y))
B = [x, (x, y)]

Different meanings of brackets in Python

I am curious, what do the 3 different brackets mean in Python programming? Not sure if I'm correct about this, but please correct me if I'm wrong:
[] - Normally used for dictionaries, list items
() - Used to identify params
{} - I have no idea what this does...
Or if these brackets can be used for other purposes, any advice is welcomed! Thanks!
Square brackets: []
Lists and indexing/lookup/slicing
Lists: [], [1, 2, 3], [i**2 for i in range(5)]
Indexing: 'abc'[0] → 'a'
Lookup: {0: 10}[0] → 10
Slicing: 'abc'[:2] → 'ab'
Parentheses: () (AKA "round brackets")
Tuples, order of operations, generator expressions, function calls and other syntax.
Tuples: (), (1, 2, 3)
Although tuples can be created without parentheses: t = 1, 2 → (1, 2)
Order of operations: (n-1)**2
Generator expressions: (i**2 for i in range(5))
Function or method calls: print(), int(), range(5), '1 2'.split(' ')
with a generator expression: sum(i**2 for i in range(5))
Curly braces: {}
Dictionaries and sets, as well as in string formatting
Dicts: {}, {0: 10}, {i: i**2 for i in range(5)}
Sets: {0}, {i**2 for i in range(5)}
Except the empty set: set()
In string formatting to indicate replacement fields:
F-strings: f'{foobar}'
Format strings: '{}'.format(foobar)
Regular expressions
All of these brackets are also used in regex. Basically, [] are used for character classes, () for grouping, and {} for repetition. For details, see The Regular Expressions FAQ.
Angle brackets: <>
Used when representing certain objects like functions, classes, and class instances if the class doesn't override __repr__(), for example:
>>> print
<built-in function print>
>>> zip
<class 'zip'>
>>> zip()
<zip object at 0x7f95df5a7340>
(Note that these aren't proper Unicode angle brackets, like ⟨⟩, but repurposed less-than and greater-than signs.)
In addition to Maltysen's answer and for future readers: you can define the () and [] operators in a class, by defining the methods:
__call__(self[, args...]) for ()
__getitem__(self, key) for []
An example is numpy.mgrid[...]. In this way you can define it on your custom-made objects for any purpose you like.
() parentheses are used for order of operations, or order of evaluation, and are referred to as tuples.
[] brackets are used for lists. List contents can be changed, unlike tuple content.
{} are used to define a dictionary in a "list" called a literal.
Tuple is immutable(order inside it can't be changed once created),and are enclosed in parenthesis,separated by ("," or ','). Tuple is used to store multiple items in a single variable.
Example:
thistupple("apple","banana","mango")
print(thistupple)
Output:
('apple', 'banana', 'cherry')

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'>

Categories