A way for iterable zip like single element for Python - python

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.

Related

Conver a list of tuple to list, modify it , then convert it back

I want to write a function, where I want to remove overlapping intervals from the second parameter.
The parameters (list of tuple) are integer intervals, for example:[(8, 23)]. End if its overlaps with first parameter, remove the overlapping interval from it. For example:
If the first parameter is [(0, 10)] and the second is [(8, 23)], I want change the second parameter to [(11, 23)].
I tried like this:
def remove_overlapping_products(brand_positions, product_positions):
brand_pos_list = list(brand_positions)
product_pos_list = list(product_positions)
def check_overlap(brand_pos_list, product_pos_list):
if product_pos_list[0]>= brand_pos_list[0] and product_pos_list[0]<= brand_pos_list[1]:
product_pos_list[0] = brand_pos_list[1]-1
return True
if product_pos_list[1]>= brand_pos_list[0] and product_pos_list[1]<= brand_pos_list[1]:
product_pos_list[1] = brand_pos_list[0]-1
return True
for x in brand_pos_list:
for y in product_pos_list:
check_overlap(x, y)
product_positions_new = tuple(product_pos_list)
return [pos for pos in product_positions_new]
But I got the error message:
"'tuple' object does not support item assignment". Since I used a converted list, I can't understand the reason of this message.
Can someone help me with my code?
If you want to change the second parameter only, it can be a shorter solution:
def check_overlap(x,y):
return True if x[1]>=y[0] else False
def remove_overlap(brand_positions, product_positions):
return [(x[1]+1, y[1]) if (check_overlap(x, y) and x[1]<y[1]) else y for (x, y) in zip(brand_positions, product_positions)]
Example:
X = [(0,10), (2,5), (6,9)]
Y = [(8,23), (5,7), (1,7)]
print(remove_overlap(X,Y))
Output:
[(11, 23), (6, 7), (1, 7)]

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

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

Unpack error with tuple of tuples?

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

Reversing a nested tuple in Python using the function reversed

I have a tuple and would like to reverse it in Python.
The tuple looks like this : (2, (4, (1, (10, None)))).
I tried reversing in Python by:
a = (2, (4, (1, (10, None))))
b = reversed(a)
It returns me this:
<reversed object at 0x02C73270>
How do I get the reverse of a? Or must I write a function to do this?
The result should look like this:
((((None, 10), 1), 4), 2)
def my_reverser(x):
try:
x_ = x[::-1]
except TypeError:
return x
else:
return x if len(x) == 1 else tuple(my_reverser(e) for e in x_)
Try this deep-reverse function:
def deep_reverse(t):
return tuple(deep_reverse(x) if isinstance(x, tuple) else x
for x in reversed(t))
This will handle arbitrarily nested tuples, not just two-tuples.
As explained in the documentation, the reversed function returns an iterator (hence the <reversed at ...>). If you want to get a list or a tuple out of it, just use list(reversed(...)) or tuple(reversed(...)).
However, it's only part of our problem: you'll be reversing the initial object (2, (...)) as (...,2), while the ... stays the same. You have to implement a recursive reverse: if one element of your input tuple is an iterable, you need to reverse it to.
It does not make sense to do this with reversed, sorry. But a simple recursive function would return what you want:
def reversedLinkedTuple(t):
if t is None:
return t
a, b = t
return reversedLinkedTuple(b), a
reversed is usable only on reversible iterable objects like lists, tuples and the like. What you are using (a linked list) isn't iterable in the sense of the Python built-in iter.
You could write a wrapping class for your linked list which implements this and then offers a reverse iterator, but I think that would be overkill and would not really suit your needs.
def reverse(x):
while x >= 0:
print(x)
x = x = 1
reverse(x)

Categories