Does the usage of parentheses have any effect whatsoever in the variable declaration syntax of a Python for loop?
Example 1: basic for loop declaring i with no parenthesis
>>> for i in range(0,10): print(i)
...
0
1
2
3
4
5
6
7
8
9
Basic for loop declaring i with arbitrary parentheses
for (((((i))))) in range(0,10): print(i)
...
0
1
2
3
4
5
6
7
8
9
For loop which unpacks two values, declared with no parentheses
>>> for x,y in zip(range(0,10), range(0,10)): print(x,y)
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
Same thing, but with parenthesis around x, y, and both.
>>> for ((x),(y)) in zip(range(0,10), range(0,10)): print(x,y)
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
So it seems the parentheses have no effect - they are not interpreted as creating, for example, a tuple. Am I correct, or is there any reason to use parentheses in a for loop variable declaration?
You can even, apparently, say this:
>>> for [x,y] in zip(range(0,10), range(0,10)): print(x,y)
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
...and the list notation (brackets) appear to have no effect either.
Just parenthesis around an expression only act to group the expression (to override operator precedence, to be able to span multiple lines, etc.).
If you wanted to create tuples, use a comma:
>>> 1
1
>>> 1,
(1,)
is there any reason to use parentheses in a for loop variable
declaration?
Yes, you need them to unpack more complex iterables. Specifically, nested iterables such as this one:
enumerate(zip(range(10), range(10, 20)))
Using parenthesis, everything works fine:
>>> for x, (y, z) in enumerate(zip(range(10), range(10, 20))):
... print("x=", x, "y=", y, "z=", z)
...
x= 0 y= 0 z= 10
x= 1 y= 1 z= 11
x= 2 y= 2 z= 12
x= 3 y= 3 z= 13
x= 4 y= 4 z= 14
x= 5 y= 5 z= 15
x= 6 y= 6 z= 16
x= 7 y= 7 z= 17
x= 8 y= 8 z= 18
x= 9 y= 9 z= 19
>>>
because x, (y, z) matches the structure of the iterables returned by:
enumerate(zip(range(10), range(10, 20)))
Without the parenthesis however, you will raise a ValueError:
>>> for x, y, z in enumerate(zip(range(10), range(10, 20))):
... print("x=", x, "y=", y, "z=", z)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack
>>>
because Python sees x, y, z and therefore expects:
enumerate(zip(range(10), range(10, 20)))
to return three-item iterables when it only returns two-item ones (tuples with a number and another two-item tuple):
>>> for item in enumerate(zip(range(10), range(10, 20))):
... print(item)
...
(0, (0, 10))
(1, (1, 11))
(2, (2, 12))
(3, (3, 13))
(4, (4, 14))
(5, (5, 15))
(6, (6, 16))
(7, (7, 17))
(8, (8, 18))
(9, (9, 19))
>>>
With the exception of the empty tuple (), it is not the parentheses which define a tuple, it's the commas. Parentheses simply keep the tuple items separate from surrounding code.
# These are all identical: x is a tuple with 2 elements.
x = (1, 2)
(x) = (1, 2)
x = 1, 2
(x) = 1, 2
# These are all identical: x is assigned the first element of the tuple (1, 2)
x, = (1, 2)
(x,) = (1, 2)
x, = 1, 2
(x,) = 1, 2
Related
I have a list named newList and inside the list there is another list of information with JSON code. I want to iterate every two elements in the newList to do something for those two elements.
ex: if my newList length is 8, I want to able do a for loop or access the 0 and 1 element, do something with the information inside those two elements, then go to 1 and 2 elements and do something with those elements.
My code:
data = np.arange(len(newList))
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return zip(a, b)
for v, w in pairwise(data):
print(v, w)
print result:
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
What I am looking for:
0 1
2 3
4 5
6 7
8 9
10 11
12 13
14 15
You can create a single iterator and then zip it with itself:
def pairwise(iterable):
return zip(*[iter(iterable)]*2)
which is similar to:
def pairwise(iterable):
i = iter(iterable)
return zip(i, i)
Do you want (0, 1), (1, 2) or (0, 1), (2, 3)? Your question seems to say you want one, and it seems to say you want the other.
Anyway, here's some code for the latter:
#!/usr/local/cpython-3.8/bin/python3
import itertools
def test_data(n):
# Yes, there's a simpler way of doing this.
for i in range(n):
yield i
def two_up(iterable):
left_iterable, right_iterable = itertools.tee(iterable)
left_every_other = itertools.islice(left_iterable, 0, None, 2)
right_every_other = itertools.islice(right_iterable, 1, None, 2)
for tuple_ in zip(left_every_other, right_every_other):
yield tuple_
def main():
it = test_data(10)
for thing in two_up(it):
print(thing)
main()
This question already has answers here:
How to get the cartesian product of multiple lists
(17 answers)
Closed 3 years ago.
I have a bit of code that runs some stats for a moving 3D window at varying size. I have created a loop to to do this in increments of 5 from 5 to 50 as below.
For example first X = 5, Y = 5, Z = 5, then X = 10, Y = 10, z = 10 etc.
This works fine, but what I'd like to do is run the loop with every possible combination of X, Y and Z in increments of 5.
For example
X Y Z
5 5 5
10 5 5
15 5 5
.. .. ..
50 5 5
5 10 5
5 15 5
5 20 5
.. .. ..
10 10 5
10 15 5
etc,
so all in all it would be 1000 possible combinations I think
Can i do this with something like itertools.permutations?
I'm pretty new to python and coding so help would be much appreciated
#python code
sizeX = (0)
sizeY = (0)
sizeZ = (0)
count = (0)
for i in range(0,10):
count = (count + 1)
sizeX = (sizeX + 5)
sizeY = (sizeY + 5)
sizeZ = (sizeZ + 5)
#run the code
If you know you will have 3 variables for certain, you can use nested for loops with range:
for i in range(5, 55, 5):
for j in range(5, 55, 5):
for k in range(5, 55, 5):
print(i, j, k)
I have a list of Numpy arrays with the same shape (but not necessarily the same dtype) and I want to iterate over the elements of all the arrays at the same time. For instance, if the arrays are:
>>> a = np.array([[1,2,3], [4,5,6]])
>>> b = np.array([['one','two','three'],['four','five','six']])
I want the iteration over [a, b] to yield
[(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five'), (6, 'six')]
I have found that numpy.nditer does almost what I need. This works:
>>> for x, y in np.nditer([a, b]):
... print('{} {}'.format(x, y))
1 one
2 two
3 three
4 four
5 five
6 six
Note that the iterator yields tuples of scalars:
>>> next(np.nditer([a, b]))
(array(1), array('one', dtype='<U5'))
However, in the corner case of a list containing one array,np.nditer directly yields the array elements:
>>> next(np.nditer([a]))
array(1)
I need it to yield a tuple with one element because I am unpacking the iterated values in the arguments of a function within the loop.
How do I convince np.nditer to yield a one-element tuple when iterating over a list of one array?
One workaround would be np.atleast_1D:
a = sum(np.ogrid[2:4, 3:5])
b = 2*a
for z in map(np.atleast_1d, np.nditer([a, b])):
print(np.arange(*z))
#[5 6 7 8 9]
#[ 6 7 8 9 10 11]
#[ 6 7 8 9 10 11]
#[ 7 8 9 10 11 12 13]
for z in map(np.atleast_1d, np.nditer([a])):
print(np.arange(*z))
#[0 1 2 3 4]
#[0 1 2 3 4 5]
#[0 1 2 3 4 5]
#[0 1 2 3 4 5 6]
Note that this unpacks the 0D arrays nditer returns into proper scalars. Also, it yields arrays, not tuples but as you just want to splat them to a function it shouldn't matter.
That goes against the behaviour of nditer.
Maybe you can always supply an array of None so that you always get a tuple? You have to handle the None in the function though.
my_list=[1,2,3,4,5]
i = 10
while i < 10:
print i ,my_list
i = i +1
My desired output:
1,1
2,2
3,3
4,4
5,5
6,1
7,2
8,3
9,4
10,5
How can I achieve this?
my_list=[1,2,3,4,5]
for index, item in enumerate(my_list*2, start = 1):
print index,item
Your task is what itertools.cycle is built for (from Python's standard library):
In [5]: from itertools import cycle
In [6]: for i, j in zip(xrange(1, 11), cycle(my_list)):
...: print i, j
...:
1 1
2 2
3 3
4 4
5 5
6 1
7 2
8 3
9 4
10 5
In [7]: for i, j in zip(xrange(12), cycle(my_list)):
...: print i, j
...:
0 1
1 2
2 3
3 4
4 5
5 1
6 2
7 3
8 4
9 5
10 1
11 2
for x in range(10):
print(x+1,list[x%len(list)])
This code is unchecked and you may need to modify it a bit.
You can try this easier way :
my_list = [1,2,3,4,5]
newList = (enumerate(my_list*2))
for num in newList:
print(num)
Output:
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 1)
(6, 2)
(7, 3)
(8, 4)
(9, 5)
I am trying to determine the optimum value of Z in a data table using Python. The optimum of Z occurs when the difference in Y values is greater than 10. In my code I am assigning the elements of each entry into a class. In order to determine the optimum I therefore need to access the previously calculated value of Y and subtract it from the new value. This all seems very cumbersome to me so if you know of a better way I can perform these type of calculations please let me know. My sample data table is:
X Y Z
1 5 10
2 3 20
3 4 30
4 6 40
5 12 50
6 12 60
7 34 70
8 5 80
My code so far is:
class values:
def __init__(self, X, Y, Z):
self.X = X
self.Y = Y
self.Z = Z
#Diff = Y2 - Y1
#if Diff > 10:
#optimum = Z
#else:
#pass
#optimum
valueLst = []
f = open('sample.txt','r')
for i in f:
X = i.split('\t')[0]
Y = i.split('\t')[1]
Z = i.split('\t')[2]
x = values(X,Y,Z)
valueLst.append(x)
An example of the operation I would like to achieve is shown in the following table. The difference in Y values is calculated in the third column, I would like to return value of Z when the difference is 22 i.e. Z value of 70.
1 2 10
2 3 1 20
3 4 1 30
4 6 2 40
5 12 6 50
6 12 0 60
7 34 22 70
8 35 1 80
Any help would be much appreciated.
A class seems like overkill for this. Why not a list of (x, y, z) tuples?
valueLst = []
for i in f:
valueLst.append(tuple(i.split('\t')))
You can then determine the differences between the y values and get the last item z from the 3-tuple corresponding to the largest delta-y:
yDiffs = [0] + list(valueLst[i][1] - valueLst[i-1][1]
for i in range(1, len(valueLst)))
bestZVal = valueLst[yDiffs.index(max(yDiffs))][2]
To start, you can put the columns into a list data structure:
f = open('sample.txt','r')
x, y, z = [], [], []
for i in f:
ix, iy, iz = map(int, i.split('\t')) # the map function changes each number
# to an integer from a string
y.append(iy)
z.append(iz)
When you have data structures, you can use them together to get other data structures you want.
Then you can get each difference starting from the second y:
differences = [y[i] - y[i+1] for i in range(1,len(y))]
What you want is the z at the same index as the max of the differences, so:
maxIndex = y.index(max(differences))
answer = z[maxIndex]
Skipping the building of tuples x, y and z
diffs = [curr-prev for curr, prev in izip(islice(y, 1, None), islice(y, len(y)-1))]
max_diff = max(diffs)
Z = y[diffs.index(max_diff)+1]
Given a file with this content:
1 5 10
2 3 20
3 4 30
4 6 40
5 12 50
6 12 60
7 34 70
8 5 80
You can read the file and convert to a list of tuples like so:
data=[]
with open('value_list.txt') as f:
for line in f:
x,y,z=map(int,line.split())
data.append((x,y,z))
print(data)
Prints:
[(1, 5, 10), (2, 3, 20), (3, 4, 30), (4, 6, 40), (5, 12, 50), (6, 12, 60), (7, 34, 70), (8, 5, 80)]
Then you can use that data to find tuples that meet your criteria using a list comprehension. In this case y-previous y>10:
tgt=10
print([data[i][2] for i in range(1,len(data)) if data[i][1]-data[i-1][1]>tgt])
[70]