Python increment in a list - python

i have this code below :
list = [254,255,256]
# Getting length of list using len() function
length = len(list)
i = 0
counter = 0
while i < length:
url = "https://test/api/v1/implantacao/projeto/{}/tarefa?start={}&limit=50".format(list[i], counter)
i += 1
counter += 1
print(url)
Output :
https://test/api/v1/implantacao/projeto/254/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=2&limit=50
But i want this output, with the last number (counter) 0 to 3 to every item on the list :
https://test/api/v1/implantacao/projeto/254/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=3&limit=50
How can i get this result ?

Compute a product of two individual lists, [254, 255] and [0,1,2,3]. Then you can simply iterate over the pairs in the product with one loop.
from itertools import product
template = "https://test/api/v1/implantacao/projeto/{}/tarefa?start={}&limit=50"
for project, start in product([254,255], [0,1,2,3]):
url = template.format(project, counter)

Instead of keeping two counters, you can use for loops like this:
urlformat = "https://test/api/v1/implantacao/projeto/{}/tarefa?start={}&limit=50"
items = [254,255,256]
for item in items:
for j in range(4):
url = urlformat.format(item, j)
print(url)
Result:
https://test/api/v1/implantacao/projeto/254/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=3&limit=50

lists = [254,255,256]
# Getting length of list using len() function
length = len(lists)
for li in range(length):
for count in range(4):
url = "https://test/api/v1/implantacao/projeto/{}/tarefa?start={}&limit=50".format(lists[li], count)
print(url)
result:
https://test/api/v1/implantacao/projeto/254/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=3&limit=50
and never use built-in as variable please

Try this:
for item in list:
for i in range(4):
url = f"https://test/api/v1/implantacao/projeto/{item}/tarefa?start=
{i}&limit=50"
print(url)
using f string is much better than using .format() str method in most cases i recommend you read about it in python documentation.
Alas the above code will give you the result you want.

One possible approach would be, as #chepner suggested, computing the cartesian product of two lists; namely [254, 255, 256] and [0,1,2,3] to obtain:
[(254, 0), (254, 1), (254, 2), (254, 3), (255, 0), (255, 1), (255, 2), (255, 3), (256, 0), (256, 1), (256, 2), (256, 3)]
Then, map the anonymous function:
lambda xy: template.format(xy[0], xy[1]),
over that list of pairs to produce the desired output, and join the list using the newline character ("\n").
def main():
template = "https://test/api/v1/implantacao/projeto/{}/tarefa?start={}&limit=50"
xs = [254, 255, 256]
ys = [0, 1, 2, 3]
cartesianProduct = [(x, y) for x in xs for y in ys]
print(
"\n".join(map(
lambda xy: template.format(xy[0], xy[1]),
cartesianProduct
))
)
if __name__ == '__main__':
main()
Output:
https://test/api/v1/implantacao/projeto/254/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/254/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/255/tarefa?start=3&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=0&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=1&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=2&limit=50
https://test/api/v1/implantacao/projeto/256/tarefa?start=3&limit=50

Related

how to store arrays inside tuple in Python?

I have a simple question in python. How can I store arrays inside a tuple in Python. For example:
I want the output of my code to be like this:
bnds = ((0, 1), (0, 1), (0, 1), (0, 1))
So I want (0, 1) to be repeated for a specific number of times inside a tuple!
I have tried to use the following code to loop over a tuple:
g = (())
for i in range(4):
b1 = (0,1) * (i)
g = (g) + (b1)
print(g)
However, the output is :
(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
Maybe this is a simple question but I am still beginner in python!
Any help!
You could create a list, fill it up, then convert it to a tuple.
g = []
b1 = (0, 1)
for i in range(4):
g.append(b1)
g = tuple(g)
print(g)
There are cleaner ways to do it, but I wanted to adapt your code in order to help you understand what is happening.
you can do this way
>>> result =tuple((0,1) for _ in range(4))
>>> result
((0, 1), (0, 1), (0, 1), (0, 1))
A possible solution is this one:
g = tuple((0,1) for i in range(4))
You can't change the items in tuple. Create g as a list then convert it into a tuple.
g = []
for i in range(4):
b1 = (0,1) * (i)
g .append(b1)
g = tuple(g)
Using list comprehension makes the code faster :
g = tuple([(0,1)*i for i in range(4)])
To get the output asked:
g = tuple([(0,1) for i in range(4)])

Count the maximum number of 0s between two 1s in list python

I want to count the 0s between two 1s from a list.
For example:
l = [0,1,0,0,0,0,1,1,1,0,0,1,0,1,1,0]
I want the output to be [4,2,1]. How can I do that in python?
A slightly different way using itertools.groupby - using the fact that any entries beyond the first and last 1 is irrelevant to us
from itertools import groupby
first_one = l.index(1) # index of the first "1"
last_one = len(l) - l[::-1].index(1) - 1 # index of the last "1"
out = [len(list(g)) for k, g in groupby(l[first_one:last_one], key=lambda x: x == 0) if k]
Output
[4, 2, 1]
My one-liner
Just for fun (not that I encourage doing so in real project), here is a one liner (but a big line), using almost all iterators in itertools (well, not nearly, in reality. There are really lot of them)
(y for (x,y),(z,t) in itertools.pairwise(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))) if x==0)
It's an iterator, and nowhere in the process do I build any list. So it would work f l was itself an iterator giving billions of 1 and 0, without using any memory
Explanation
itertools.groupby(l)
is an iterator giving subiterators for each new value of l.
So
for v,it in itertools.groupby(l):
for x in it:
print(x)
Just prints all elements of l. But with 9 iterations for x in it, one in which x is 1 time 0, then one in which x is 1 time 1, then one in which x is 4 times 0, then etc.
If y is an iterator, then sum(1 for _ in y) is the number of iterations.
So
((x,sum(1 for _ in y)) for x,y in itertools.groupby(l))
iterates pairs (value0or1, numberOfSuchInGroup), with alternating value0or1
For example
list((x,sum(1 for _ in y)) for x,y in itertools.groupby(l))
here is
[(0, 1), (1, 1), (0, 4), (1, 3), (0, 2), (1, 1), (0, 1), (1, 2), (0, 1)]
If want to drop the first pair, at least if it is a group of 0, since leading 0 does not count. Plus, I want to play with another iterator, which is dropwhile. So
itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))
is the same iterator as before. But without the first pair if it is group of 0
list(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l))))
is
[(1, 1), (0, 4), (1, 3), (0, 2), (1, 1), (0, 1), (1, 2), (0, 1)]
I also want do drop the last pair (at least if it is a group of 0, but it doesn't hurt if I drop it also if it is a group of 1). And I haven't played with pairwise yet. Which iterates through pairs of subsequent elemnents
list(itertools.pairwise(range(5)))
is
((0,1),(1,2),(2,3),(3,4))
for example
Here, I use it for a very silly reason: just to drop the last item, since of course, there is one less item in pairwise iteration. In my last example, we have 4 items
list(x for x,y in itertools.pairwise(range(5)))
is
[0,1,2,3]
So, strange usage of pairwise, but it drops the last iteration used that way.
So in our case
((x,y) for (x,y),(z,t) in itertools.pairwise(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))))
is the same iterator as before, but without the last pair
list((x,y) for (x,y),(z,t) in itertools.pairwise(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))))
is
[(1, 1), (0, 4), (1, 3), (0, 2), (1, 1), (0, 1), (1, 2)]
Now that we have only groups of 0 that are valid, we can filter out the 1s
list((x,y) for (x,y),(z,t) in itertools.pairwise(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))) if x==0)
is
[(0, 4), (0, 2), (0, 1)]
Plus, we don't need the 0s because at this stage they are all 0 anyway.
So, keep just y not (x,y)
list(y for (x,y),(z,t) in itertools.pairwise(itertools.dropwhile(lambda x: x[0]==0, ((x,sum(1 for _ in y)) for x,y in itertools.groupby(l)))) if x==0)
Is
[4,2,1]
One option using pandas:
l = [0,1,0,0,0,0,1,1,1,0,0,1,0,1,1,0]
s = pd.Series(l)
out = (s[s.eq(0)&s.cummax()&s.loc[::-1].cummax()]
.rsub(1).groupby(s.ne(0).cumsum()).sum()
.tolist()
)
With pure python and itertools.groupby:
from itertools import groupby
l = [0,1,0,0,0,0,1,1,1,0,0,1,0,1,1,0]
out = []
start = False
for k, g in groupby(l):
if k == 1:
if start:
out.append(count)
start = True
else:
count = len(list(g))
output: [4, 2, 1]
An old-school answer.
def count(l: list[int]) -> list[int]:
res = []
counter = 0
lastx = l[0]
for x in l[1:]:
rising = (x-lastx) > 0
if rising and counter != 0:
res.append(counter)
counter = counter+1 if x==0 else 0
lastx = x
return res
count([0,1,0,0,0,0,1,1,1,0,0,1,0,1,1,0]) # [4, 2, 1]
How about this, explanation is all in the code:
l = [0,1,0,0,0,0,1,1,1,0,0,1,0,1,1,0]
output = []
for i in range(len(l)): #this goes through every index in l (1,2,3,...15, 16)
if l[i] == 1: #if in the list at the current index is a 1 it
zeros = 0 #sets zeros to 0
while l[i+1+zeros] == 0: #and starts a while loop as long as the current index+1+'the amount of zeros after the last number 1' is a zero. (so it stops when it reaches another 1)
zeros += 1 # because the while loop still runs it adds another 0
if i+1+zeros == len(l): #the current index + 1 + 'the amount of zeros' = the length of our list
zeros = 0 # it sets zeros back to 0 so the program doesn't add them to the output (else the output would be [4, 2, 1, 1])
break #breaks out of the loop
if zeros > 0: #if the zeros counted between two 1s are more then 0:
output.append(zeros) # it adds them to our final output
print(output) #prints [4, 2, 1] to the terminal

Python calculating area of rectangle for elements of a list

I have a list like that and I want to calculate the area of rectangle for elements of this list.
list = [(3,4),(10,3),(5,6),(1,9)]
output = 12, 30, 30, 9
I tried this code but output is 12,12,12,12
list = [(3,4),(10,3),(5,6),(1,9)]
def calc(x,):
for i,j in list:
return i*j
print(list(map(calc, list)))
That is because the usage of map() is wrong. What map does is apply the function on each element of the iterable and replaces that element with the returned value.
For your list, each element is a tuple of two elements so your calc() should he something like this:
def calc(x):
return x[0] * x[1]
Try this way:
def calc(lst):
final = []
for i,j in lst.items():
final.append(i * j)
return final
your_list = [(3,4),(10,3),(5,6),(1,9)]
print(calc(your_list))
To make your life easier you can just add a list inside the function calc() and return the list and it should return [12, 30, 30, 9].
number_list = [(3, 4), (10, 3), (5, 6), (1, 9)]
def calc(x):
result = []
for i, j in x:
result.append(i*j)
return result
Edit: As to use the map function.
If you really want to do it your way then you should do it like this:
number_list = [(3, 4), (10, 3), (5, 6), (1, 9)]
def calc(x):
return x[0] * x[1]
result = list(map(calc, number_list))
Since the map function provides each element of number_list then you cannot iterate over it like your solution. Instead just get the two elements of the tuple and multiply them.
list_of_tuples = [(3,4),(10,3),(5,6),(1,9)]
res = list(map(lambda _tup: _tup[0] * _tup[1], list_of_tuples))
Do not name your variable list!!* That's a reserved keyword in python.
calc function requires to be defined correctly here.
def calc(x):
return x[0]*x[1]
Also list is reserved keyword in Python.
You can starmap the mul function to the list:
from itertools import starmap
from operator import mul
lst = [(3,4),(10,3),(5,6),(1,9)]
list(starmap(mul, lst))
# [12, 30, 30, 9]

Efficient enumeration of ordered subsets in Python

I'm not sure of the appropriate mathematical terminology for the code I'm trying to write. I'd like to generate combinations of unique integers, where "ordered subsets" of each combination are used to exclude certain later combinations.
Hopefully an example will make this clear:
from itertools import chain, combinations
​
mylist = range(4)
max_depth = 3
rev = chain.from_iterable(combinations(mylist, i) for i in xrange(max_depth, 0, -1))
for el in list(rev):
print el
That code results in output that contains all the subsets I want, but also some extra ones that I do not. I have manually inserted comments to indicate which elements I don't want.
(0, 1, 2)
(0, 1, 3)
(0, 2, 3)
(1, 2, 3)
(0, 1) # Exclude: (0, 1, _) occurs as part of (0, 1, 2) above
(0, 2) # Exclude: (0, 2, _) occurs above
(0, 3) # Keep
(1, 2) # Exclude: (1, 2, _) occurs above
(1, 3) # Keep: (_, 1, 3) occurs above, but (1, 3, _) does not
(2, 3) # Keep
(0,) # Exclude: (0, _, _) occurs above
(1,) # Exclude: (1, _, _) occurs above
(2,) # Exclude: (2, _) occurs above
(3,) # Keep
Thus, the desired output of my generator or iterator would be:
(0, 1, 2)
(0, 1, 3)
(0, 2, 3)
(1, 2, 3)
(0, 3)
(1, 3)
(2, 3)
(3,)
I know I could make a list of all the (wanted and unwanted) combinations and then filter out the ones I don't want, but I was wondering if there was a more efficient, generator or iterator based way.
You are trying to exclude any combination that is a prefix of a previously-returned combination. Doing so is straightforward.
If a tuple t has length max_depth, it can't be a prefix of a previously-returned tuple, since any tuple it's a prefix of would have to be longer.
If a tuple t ends with mylist[-1], then it can't be a prefix of a previously-returned tuple, since there are no elements that could legally be added to the end of t to extend it.
If a tuple t has length less than max_depth and does not end with mylist[-1], then t is a prefix of the previously-returned tuple t + (mylist[-1],), and t should not be returned.
Thus, the combinations you should generate are exactly the ones of length max_depth and the shorter ones that end with mylist[-1]. The following code does so, in exactly the same order as your original code, and correctly handling cases like maxdepth > len(mylist):
def nonprefix_combinations(iterable, maxlen):
iterable = list(iterable)
if not (iterable and maxlen):
return
for comb in combinations(iterable, maxlen):
yield comb
for length in xrange(maxlen-2, -1, -1):
for comb in combinations(iterable[:-1], length):
yield comb + (iterable[-1],)
(I've assumed here that in the case where maxdepth == 0, you still don't want to include the empty tuple in your output, even though for maxdepth == 0, it isn't a prefix of a previously-returned tuple. If you do want the empty tuple in this case, you can change if not (iterable and maxlen) to if not iterable.)
I noticed an interesting pattern in your desired output and I have a generator that produces that. Does this work for all your cases?
from itertools import combinations
def orderedSetCombination(iterable, r):
# Get the last element of the iterable
last = (iterable[-1], )
# yield all the combinations of the iterable without the
# last element
for iter in combinations(iterable[:-1], r):
yield iter
# while r > 1 reduce r by 1 and yield all the combinations
while r>1:
r -= 1
for iter in combinations(iterable[:-1], r):
yield iter+last
# yield the last item
yield last
iter = [0,1,2,3]
for el in (list(orderedSetCombination(iter, 3))):
print(el)
Here is my explaination of the logic:
# All combinations that does not include the last element of the iterable
# taking r = max_depth items at a time
(0,1,2)
# from here on, its the combinations of all the elements except
# the last element and the last element is added to it.
# so here taking r = r -1 items at a time and adding the last element
# combinations([0,1,2], r=2)
(0,1,3)
(0,2,3)
(1,2,3)
# the only possible value right now at index r = 2 is the last element (3)
# since all possible values of (0,1,_) (0,2,_) (1,2,_) are already listed
# So reduce r by 1 again and continue: combinations([0,1,2], r=1)
(0, 3)
(1, 3)
(2, 3)
# continue until r == 0 and then yield the last element
(3,)

builtin_function error while making a list of permutations of 123

I want to make a sorted list of permutations of 123 but I can't use python's module. When I run this code I get the message:
'builtin_function_or_method' object has no attribute 'sort' (line 22)
n = int(input())
elements = str(input())
elements = elements.split
def factor(elements, i , n):
if i == n - 1:
return(elements)
else:
for j in range(i, n):
elements[i], elements[j] = elements[j], elements[i]
factor(elements, i + 1)
elements[i], elements[j] = elements[j], elements[i]
list = []
list = factor(elements, 0, n)
list = list.sort
while True :
if list == [] : break
else:
print(list[0])
list.pop([0])
Here's one problem:
elements = elements.split
I think you meant:
elements = elements.split() # you forgot the parentheses!
Here's another similar problem:
list = list.sort # you forgot the parentheses, and the function call is wrong
I think you were looking for this:
list = sorted(list)
Or this:
list.sort() # no assignment here, it's an in-place sort
Also, a word of advice: it's a bad idea to call a variable list, it clashes with a built-in type and a function name. Some final words: what you want to do is already implemented in a standard module, give this a try:
import itertools as it
list(it.permutations([1, 2, 3])) # see? told you `list` was a function!
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

Categories

Resources