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)]
Related
I have a tuple like (p1, p2) (for example (5,3) or (2,1))
I want to apply the same operation to each element of the tuple. (Incidentally this operation will give for each element another tuple, so I will have a tuple of tuples but this is not a necessary condition)
First I thought something like
for element in (3,2):
res=function(element)
but first, this doesn't seem a elegant solution and two, I would still have to form a tuple from each res to get a (function(3),function(2)) solution
How can I apply a function (with several arguments) to each element of the tuple once and get a tuple of returned values?
If I understand you question correctly, map should to the job as well:
tuple(map(func, tpl))
where func is a one-argument function you defined.
Now, if you have a function with several arguments you would like to apply to each element, like:
def func(x, y, z): return x*y+z
I assume that 2 elements (let's take y and z) are fixed, while x will be determined by the value in the tuple.
There are two approaches in my view:
Either you define a new function with 2 fixed arguments and map:
def func1(x): return func(x, 3, 2)
tuple(map(func1, tpl))
Or map as follows (I think it is less elegant, but it is a matter of tastes, maybe):
tuple(map(lambda x: func(x, 3, 2), tpl))
One approach uses a list comprehension:
def add_one(x):
return x + 1
tpl = (5, 3)
output = tuple([add_one(x) for x in tpl])
print(output) # (6, 4)
You may consider using the generator comprehension then convert it to tuple:
>>> data = (3, 5, 7, 9)
>>> tuple((function(x) for x in data))
Hi guys I just want to know if there's a way to iterate over a tuple that behaves like zip.
For example:
zipper = zip(['aye', 'bee'], ['ex', 'why'])
for x, y in zipper:
print(x, y)
aye ex
bee why
tupl = 3, 2
for x, y in tupl:
print(x, y)
# 'int' object is not iterable.
What I knew now is that it can't be zip-ed:
tupl = zip(3, 2)
# zip argument #1 must support iteration
I am trying to pass zipper into a function, I also hope to pass the tuple or a single set of zip.
def processthis(zipper):
for x, y in zipper:
# do something with x and y
With a loop of for x, y in tupl: you are expecting tupl to be a sequence of tuples, rather than a tuple.
If you want your loop to process only one tuple you should assign tupl with [(3, 2)] instead of (3, 2).
Parenthesis are missing.
When passing a tuple to function, it needs to be wrapped by parenthesis.
In your case,
zip((3, 2), (4, 5)) # zipping 2 tuples
Otherwise, zip will sees 3 and 2 as two positional arguments.
I want to iterate over the elements ((a,b),(x,y)) so I tried:
def method(tuple):
((a,b),(x,y))= tuple
for element in tuple:
.....
But then I read another stackoverflow page which suggested something like this:
def method(tuple):
((a,b),(x,y))= tuple
for element in tuple[0:4]:
.....
Both resulted in the error: ValueError: need more than 1 value to unpack.
Is this action not allowed in python, or do I just have a syntax problem?
I have checked the python docs as well.
Thanks for any advice.
Edit
map = ((1,0),(3,2))
def count(map):
((a,b),(x,y))= tuple
inc=0
for element in tuple:
inc+=1
If you have a tuple of tuples, of the form ((a, b), (x, y)), you can iterate over its elements:
def method(tuples):
for tup in tuples:
for e in tup:
print e
If you want to have 4 variables, you can use them separately:
def method(tuples):
(a, b), (x, y) = tuples
print a, b, x, y
Note:
Don't use Python built-in names as name of variables. In other words, don't use tupleas a name of a variable because it's a type in Python. Use something else, like tuples, my_tuple, ...
Right now my function is not recoginizing my numbers in the list coeff as numbers. I am trying to pair up items from the two list and then sort them into a different list based on the value of mul. But everything is going into the negative list. How to i make sure it is considering mul as a number going into each if statement.
def balance_equation(species,coeff):
data=zip(coeff,species)
positive=[]
negative=[]
for (mul,el) in data:
if mul<0:
negative.append((el,mul))
if mul>0:
positive.append((el,mul))
Edit;
I ment to originally include this
balance_equation(['H2O','A2'],['6','-4'])
Your problem is that in the way you call it (balance_equation(['H2O','A2'],['6','-4'])), mul is a string rather than an int ('6' or '-4' rather than 6 or -4). Change your if statement to:
if int(mul)<0:
negative.append((el,mul))
if int(mul)>0:
positive.append((el,mul))
This converts mul to an integer before comparing it to 0.
Well, the first problem is that your function just returns None, just throwing away the two lists, so there's no way to even see whether it's doing the right thing.
If you fix that, you'll see that it is doing the right thing.
def balance_equation(species,coeff):
data=zip(coeff,species)
positive=[]
negative=[]
for (mul,el) in data:
if mul<0:
negative.append((el,mul))
if mul>0:
positive.append((el,mul))
return negative, positive
>>> n, p = balance_equation(balance_equation('abcdef', range(-3,3))
>>> n
[('a', -3), ('b', -2), ('c', -1)]
>>> p
[('e', 1), ('f', 2)]
So, there are two possibilities:
Since the code you pasted is clearly not the actual code you're running, maybe you fixed the bug while rewriting it to post here.
You're not calling it with sensible inputs. For example, if you pass the parameters backward, since species is presumably a collection of strings, they'll all end up positive. Or, likewise, if you pass the coeffs as string representations of integers.
If it's the last problem—you're passing, say, 'abcdef', ['-3', '-2', '-1', '0', '1', '2', '3'], and you want to deal with that within balance_equation instead of in the calling code, that's easy. Just add this line before the zip:
coeff = [int(x) for x in coeff]
Or change your zip to:
data = zip((int(x) for x in coeff), species)
By the way, I'm assuming you're on CPython 2. In Python 3, trying to compare a string to 0 will raise a TypeError instead of always returning True, while in other Python 2 implementations it might always return False instead of True…
I think you have your answer, but there's also a simpler way of doing this in Python:
for (mul, el) in data:
append_to = negative.append if mul < 0 else positive.append
append_to(el)
Not sure what "should happen" to 0 though
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.