Unpack error with tuple of tuples? - python

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, ...

Related

How to apply some operation to each element of a tuple

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

Julia: Passing Dict items as arguments to a function

I am trying to pass a Dict to a function in Julia. The Dict contains pairs of argument names and their respective values. Let's say I have a function f and a Dict d:
julia> function f(x=10, y=10, z=10); return x^2, y^2, z^2; end
julia> d = Dict("x"=>3, "z"=>7, "y"=>5)
This throws a MethodError:
julia> f(d...)
ERROR: MethodError: no method matching ^(::Pair{String,Int64}, ::Int64)
I also tried using a NamedTuple, but this seems useless as it is sensitive to the order of the elements in the tuple and doesn't match their names with the function argument names:
julia> t = (x=3, z=7, y=5)
julia> f(t...)
(9, 49, 25)
I am sure there is a way to do this. Am trying to do this with the wrong types? In python, what I am looking for would look like this:
>>> def f(x=10, y=10, z=10):
... return x**2, y**2, z**2
>>> d = {'x':3, 'z':7, 'y':5}
>>> f(**d)
(9, 25, 49)
Firstly, since you want the names of the arguments to be important (keyword arguments) you need to use a ; in the function definition:
f(;x=10, y=10, z=10) = x^2, y^2, z^2
Secondly, you should use a dictionary where the keys are Symbols:
d = Dict(:x=>3, :z=>7, :y=>5)
And thirdly, you want to indicate that you are splatting keyword arguments by splatting after ;:
f(;d...)
# giving the result (9, 25, 49)
It seems that you need to square all values of a dictionary. use comprehension maybe a better solution.
d = Dict(:x=>3, :z=>7, :y=>5)
[println(p.first, "=> ", p.second^2) for p in d];
In the above, p.first will get the keys, while p.second will get values of the dictionary.

How to combine list and individual elements into one tuple in python?

I have a few variables in python3:
a = 1
b = [2,3,4]
c = 5
I want to get a tuple which is from above variables, like: (1,2,3,4,5)
what is the easiest way to do that in python3?
Creating a tuple in Python is as simple as putting the stuff you need in a tuple in parentheses:
my_tuple = (1, 2, 3)
a = 1
b = 2
c = 3
another_tuple = (a, b, c) # also works with variables, or anything else with a value
And if what you want in the tuple is in something else that can be unpacked, like a list or a tuple itself, you can use the unpacking operator * to unpack it into the new tuple:
a = 1
b = [2,3,4]
c = 5
my_tuple = (a, *b, c)
Not your question, but note that you can also get stuff from a tuple without using the * operator, as it's implied in an assignment statement:
x, _, z = my_tuple # continued from before
In this example, what was in a (1) is now also in x and what was in c also in z. What was in b and in the second position of the tuple gets discards (that's what the underscore _ here means, "don't care".)
You use the unpack operator in cases where you explicitly need to unpack and you're constructing some new variable, or need the elements of the tuple separately where they could also be used as a tuple. For example, when calling a function:
a_tuple = ('Hi there', 'John')
def greeting(phrase='Hello', name='world'):
print(f'{phrase}, {name}!')
greeting(*a_tuple)
In this example, calling greeting as greeting(a_tuple) would give you the very nasty result of ('Hi there', 'John'), world!, clearly not what you want, but you can still use the tuple with the unpack operator.
And the other obvious example is one like the one solving OP's question.
Simply create a new tuple as shown below.
newTuple=(a, *b, c)
Note: *b unpacks list b into variables and add each variable to indexes of newTuple
One of the ways is shown below
from functools import reduce
import operator
# create a bunch of lists, reduce them to one list and finally convert to tuple
result = tuple(reduce(operator.add, ([a], b, [c])))
print(result)
This is the most pythonic solution:
a = 1
b = [2,3,4]
c = 5
res = a,*b,c
# output: (1,2,3,4,5)
Note: To create the new tuple, round brackets are not necessary in Python3

Iterate a tuple with dict inside

Having trouble iterating over tuples such as this:
t = ('a','b',{'c':'d'})
for a,b,c in t:
print(a,b,c) # ValueError: not enough values to unpack (expected 3, got 1)
for a,b,*c in t:
print(a,b,c) # ValueError: not enough values to unpack (expected 2, got 1)
for a,b,**c in t:
print (a,b,c) # Syntax error (can't do **c)
Anyone know how I can preserve the dictionary value? I would like to see a='a', b='b', and c={'c':'d'}
You'd need to put t inside some other iterable container:
for a, b, c in [t]:
print(a, b, c)
The problem with your attempts is that each on is iterating over a single element from t and trying to unpack that. e.g. the first turn of the loop is trying to unpack 'a' into three places (a, b and c).
Obviously, it's also probably better to just unpack directly (no loop required):
a, b, c = t
print(a, b, c)
Why are you iterating at all when it's a single tuple? Just unpack the single tuple, if that's what you need to do:
a, b, c = t
print(a, b, c)
Or if it's just printing you want to do unpack in the call itself:
print(*t)
Try this:
for a,b,c in [t]:
print(a,b,c)
Putting t inside a list will allow you to unpack it.
You can use tuple unpacking with multiple assignment:
a, b, c = t
print(a, b, c)
try this
for x in t:
print(x)
x will take all the values in t iteratively, so 'a', then 'b' and finally {'c':'d'}.
And to print exactly a = 'a' etc you can do:
for param, val in zip(["a","b","c"], t):
print(param,"=",val)

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)]

Categories