Im trying to create a function that records the amount of times a value in a list is repeated in a row. After about an hour of deliberation, I was able to reach a stable-looking conclusion, yet i am unable to receive the desired outcome
lst = [1,2,2,2,3,1,1]
def compress(numlist):
intervals,x=0,0
for i in numlist:
if i == numlist[x]:
intervals+=1
elif i != numlist[x]:
print((intervals,numlist[x]), end=" ")
x+=intervals
intervals=1
compress(lst)
Here, I was trying to get the function to "compress" the list of integers
When I run the code, the outcome is:
(1, 1) (3, 2) (1, 3)
While the desired outcome is:
(1, 1) (3, 2) (1, 3) (2,1)
You only show a run when you find a value that is not equal to the previous one. There is no value after the last value, of course, so the last run is never printed. Just add a line after the loop to print the last run.
if intervals != 0:
print((intervals,numlist[x]))
By the way, you don't need the elif conditional. All you need there is an else, since if i == numlist[x], then the only other thing possible is i != numlist[x].
Related
I want to do a for loop that can basically do the absolute difference between every 2 elements of the array until it reaches all of them and then print the highest absolute difference.
arr = []
n = int(input("number of elements in array: "))
for i in range(0, n):
arr.append(input('insert element: '))
I've done this already but I would like to know how slow this method is compared to making the absolute difference between the
first and last element after sorting the array.
EXAMPLE
Input: {2, 7, 3, 4, 1, 9}
Output: 8 (|1 – 9|)
This is what I have tried:
arr = []
n = int(input("número de elementos do array : "))
for i in range(0, n):
arr.append(int(input('escreva os elementos: ')))
arr.sort()
print(arr[-1] - arr[0])
If you are fine with numpy, there's a way to do so.
Firstly, you need to find all the possible non-duplicate solutions from the given input using itertools.combinations
from itertools import combinations
alist = [2, 7, 3, 4, 1, 9]
all_comb = list(combinations(alist, 2))
[(2, 7), (2, 3), (2, 4), (2, 1), (2, 9), (7, 3), (7, 4), (7, 1), (7, 9), (3, 4), (3, 1), (3, 9), (4, 1), (4, 9), (1, 9)]
With this, you can use np.diff to find the differences for every tuple.
abs_diff = abs(np.diff(all_comb)).flatten()
array([5, 1, 2, 1, 7, 4, 3, 6, 2, 1, 2, 6, 3, 5, 8])
Finally, you can get the index of the maximum difference using np.argmax.
all_comb[abs_diff.argmax()]
Out[147]: (1, 9)
arr = []
n = int(input("número de elementos do array : "))
my_min, my_max = None, None
for i in range(0, n):
arr.append(int(input('escreva os elementos: ')))
if my_min is None or abs(arr[i]) < my_min:
my_min = arr[i]
if my_max is None or abs(arr[i]) > my_max:
my_max = arr[i]
print(f"{abs(my_max - my_min)} (|{my_max} - {my_min}|)")
You can achieve this just by "emembering" the number with highest and lowest abs value
As I understood about your query.
Sorting the element and then comparing first & last one is much faster than finding highest difference via iterating through list. This is because when sorting happens internally, as it moves forward it needs to compare with less values because if value is higher than last sorted value it directly appends next to it but if value is less then it just moves one value back rather than starting over again.
But comparing through all possible pairs in list takes much more time as it has to start from first value over again since we don't know which comparing will be highest.
So sorting is much faster to find largest difference than iterating for every possible pair with for loop in list.
I hope I got your query right :)
UPDATED
so the main question is about finding a way to find largest diff in a list with for loop and which should be faster so here it is.
In my opinion below code will be even faster than sorting and finding largest diff. Because here in this code we only need to iterate in list once and we will have answer of largest diff. No need to iterate every possible pair of value.
I think this may help :)
list_a = []
n = int(input("number of elements in array: "))
for i in range(0, n):
# store input after converting to integer.
list_a.append(int(input('insert element: ')))
'''to store largest difference of two current numbers in every eteration'''
largest_diff_so_far = 0;
'''list to store that two numbers we are comparing'''
actual_diff_number = None;
'''start from first number in list. we don't need to go through every possible pair so just picking first number without for loop.'''
first = list_a[0]
'''here we iterate through all number only once till last number in
list'''
for second in list_a :
'''first find diff of current two value'''
current_diff = second - first
'''as we can see when current_diff is larger then previous largest diff we will update their value'''
if largest_diff_so_far == 0 or current_diff > largest_diff_so_far:
'''if first value in list is largest than all then the current diff will be negative and in that case we will run below if code and continue the code so that it will not over -ride anything in remaining code'''
if current_diff < 0:
''' since the diff is negative we will store its absolute value in largest diff variable.'''
largest_diff_so_far = abs(current_diff)
''' since first value is largest then all means it is larger than current second also, so in actual_diff_number we will store values in reverse order, so that our largest value which is stored in first variable will be second in list and by this in later iteration we will avoid over-writing of this largest value'''
actual_diff_number = [second, first]
''' we will also update first variable's value to second variable's value since it smaller than previous value of first and by this next iteration will use this value for diff rather than initial value of first variable which was largest.'''
first = second
continue
'''if above condition is not the case than rest of the below code will run'''
'''largest diff will be current_diff'''
largest_diff_so_far = current_diff
'''storing actual number whose diff is largest till now.'''
actual_diff_number = [first, second]
'''below is main part for saving time. if in current process we find diff which is in minus means our second value is even less than first, in that case we no longer need to carry forward that first value so we will update first value to our current second value and will also update largest diff that is stored previously. since our first value is less than previous first value then our diff will also increase from previous diff.'''
elif current_diff < 0:
first = second
'''update largest diff with new first value'''
largest_diff_so_far = actual_diff_number[1] - first
'''update actual diff number's first value in that list'''
actual_diff_number[0] = first
'''finally print answer since after finishing for loop largest_diff_so_far and actual_diff_number contains the answer that we are finding.'''
print(actual_diff_number, largest_diff_so_far)
I have a large dictionary in which I am scanning an API and adding values to based on if the shots taken in a hockey game are goals or not. Here is my code right now...
for key in contents['liveData']['plays']['allPlays']:
# for plays in key['result']['event']:
# print(key)
if (key['result']['event'] == "Shot"):
#print(key['result']['event'])
scoordinates = (key['coordinates']['x'], key['coordinates']['y'])
if scoordinates not in shots:
shots[scoordinates] = (1, 0)
else:
shots[scoordinates] += (1, 0)
if (key['result']['event'] == "Goal"):
#print(key['result']['event'])
gcoordinates = (key['coordinates']['x'], key['coordinates']['y'])
if gcoordinates not in shots:
shots[gcoordinates] = (1, 1)
else:
shots[gcoordinates] += (1, 1)
I was trying to add two values to the dict by using parentheses, but this doesn't work because whenever there is a duplicate coordinate shot the table will add the value like this (1,0, 1, 1) instead of doing (2,1). Is this possible? I was thinking there might be a simple formatting fix here, but I am not totally sure.
You can use sum instead of +=:
a = tuple(map(sum, zip(a, b)))
So for this situation use:
shots[gcoordinates] = tuple(map(sum, zip((1, 1), shots[gcoordinates])))
Use the following function to sum tuples:
import operator
def sum_tuples(tuple_1, tuple_2):
return tuple(map(operator.add, tuple_1, tuple_2))
Essentially what I'm trying to do is write the enumerate function recursively. I'm fully aware that doing this recursively is not optimal and that there is already a built-in enumerate function in python.
def enumeration(mylist, idx=0):
if idx == 0:
return [(idx, mylist[idx]), enumeration(mylist, idx+1)]
elif idx != len(mylist)-1:
return (idx, mylist[idx]), enumeration(mylist, idx+1)
else:
return idx, mylist[idx]
Now it's not the enumeration part that's difficult. It's getting the tuples to match up where they should be. If mylist was set to ["The", "tree", "then"], the output would be "[(0, "the"), ((1, "tree"), (2, "then"))] when I want it to look like [(0, "the"), (1, "tree"), (2, "then")].
I know what is causing the problem but I have no idea how to fix it. I've tried using '+' instead of ',' in the return statements but that just leads to [(0, "the", 1, "tree", 2, "then")] which I also don't want.
The problem is that the return type of your enumeration is not consistent:
if the index is 0 it returns a list[pair, enumeration()]
if the index is neither 0 nor end-of-list, it returns a Pair[Pair, enumeration]
if the index is end-of-list, it returns a simple pair
You need your various cases to be consistently typed in such a way that you can "recombine" your items. Since enumeration() should return a sequence, logically each recursive case needs to return a list (of pairs).
Then you need to do a recursive case analysis. Generally, recursion consists of two items:
how do you decide to end the recursion and what do you do in that case
what do you do in the normal case
Here the terminal case is pretty simple: if you're past the end of the list, just return an empty list. Incidentally this is something you're not handling at all: try calling enumerate([]) and see what happens.
Then the normal recursive case: just generate a pair of (index, item), call enumerate() with an incremented index, and concatenate the two.
def enumerate(mylist, idx=0):
# note: terminal case is really `idx == len(mylist)`, you may want to generate an error if `idx > len(mylist)` instead as that's an incorrect use of the API
if idx >= len(mylist):
return []
else:
return [(idx, mylist[idx])] + enumerate(mylist, idx+1)
Other than the behaviour with empty lists, your version also uses idx completely differently: in the original enumerate it's just the index that's returned, it's not used to manipulate the input (indeed the input is not necessarily indexable). So e.g. enumerate(range(3), 5) would yield (5, 0), (6, 1), (7, 2). Your version would either error out or end, because it would try to access the 5th item of a range(3).
this will work
def enumeration(mylist, idx=0):
if idx == 0:
return [(idx, mylist[idx])]+(enumeration(mylist, idx+1))
elif idx < len(mylist)-1:
return [(idx, mylist[idx])]+(enumeration(mylist, idx+1))
else:
return [(idx, mylist[idx])]
output:
mylist=["asd","gsd","fff","adf"]
enumeration(mylist, idx=0)
[(0, 'asd'), (1, 'gsd'), (2, 'fff'), (3, 'adf')]
First of use a list to hold the values.
Second instead of calling the next recursion with a , use + to add to the list of values , this way each tuple gets added to the same list.
Hej Everyone,
The idea of the script is to grab image links from a catalogue page of my company's website and change them to image links with a higher resolution and filter for image format, where the variable to filter for is found in the link itself, in this case the capital P. Afterwards a csv is generated with the links.
The transformation, filtering and writing to csv works fine, but my problem is that I don't want all the 80 products, I only want 8 to be in the list nl.
The links list contains elements like this one https://rndr.mywebsite.com/media/catalog/product/seo-cache/x386/19/95/19-95-101P/How-Hard-You-Hit-Butcher-Billy-Premium-Poster.jpg
NOTE: variables ratio and creatives (inputnumber-1) are defined by commandline input. Just assume that the input was ratio = P and creatives = 9-1.
NOTE2: For quicker testing, the links list has a limit of 15 elements by now.
nl= []
string1= "https://rndr.mywebsite.com/media/catalog/product/cache/x800/"
string2= ".jpg"
while len(nl) <= creatives:
for index in range(len(links)):
if "P" in "".join(links[index].split("/", 12)[10]) and "P" in ratio:
print("YEAH", len(nl))
nl.extend([string1 + "/".join(links[index].split("/", 11)[8:11]) + string2])
else:
print ("Ups", len(nl))
print (nl)
The actual output is
('YEAH', 0)
('YEAH', 1)
('YEAH', 2)
('YEAH', 3)
('Ups', 4)
('YEAH', 4)
('YEAH', 5)
('Ups', 6)
('YEAH', 6)
('YEAH', 7)
('YEAH', 8)
('YEAH', 9)
('YEAH', 10)
('YEAH', 11)
('YEAH', 12)
[https://rndr.mywebsite.com/media/catalog/product/cache/x800/19/95/19-95-101P.jpg, transformed-link2,...,transformed-link12]
As you can see the filtering and transforming works fine, but it should stop after having 9 links in the list nl.
As mentioned by Coldspeed, in the inner loop you're adding a whole batch of items to nl, thus overshooting the limit. To fix it, you could get rid of the while loop and do this instead:
for index in range(len(links)):
if "P" in "".join(links[index].split("/", 12)[10]) and "P" in ratio:
print("YEAH", len(nl))
nl.append(string1 + "/".join(links[index].split("/", 11)[8:11]) + string2)
if len(nl) > creatives:
break
else:
print ("Ups", len(nl))
Adding a couple of print statements like this can help you figure out exactly what is going on:
while len(nl) <= creatives:
print('outer loop')
for index in range(len(links)):
print('inner loop')
...
You've got a nested loop here. What happens is, inside the inner loop, the condition for the outer loop is not checked, until the inner loop has finished iterating. What you'd need to do is put an explicit break inside the inner loop.
Look at this answer for a solution. :)
You're doing a for loop inside the while loop. The while loop will only check its condition upon finishing the first for loop, by which point you've already looped over every element in links.
E.g.
i = 0
while i < 10:
for z in range(20):
i = z
print(i)
will print all the way to 19, because the precondition for the while loop will only be checked when the inner for loop finishes.
I am currently new to Python and am trying to run a few simple lines of code. I cannot understand how Python is evaluating this syntax after the if statement. Any explanations will be appreciated.
number = int(raw_input("Enter number : "))
if number == (1 or 2 or 3):
print "Match"
else:
print "No match"
Only the integer 1 yield a positive result and any other numbers including 2 and 3 go through the else branch. Can the conditions be stated as the following only?:
if number == 1 or number == 2 or number == 3:
Thank you.
You probably want:
if number in (1, 2, 3):
Python has boolean values, such as True and False, and it also has falsy values, such as any empty list, tuple, or dictionary, an empty string, 0, and None. Truthy values are the opposite of that, namely anything that's defined.
Python's or evaluates and short-circuts on the first element that returns a truthy value.
So, the expression (1 or 2 or 3) is going to return 1.
If you want to compare against all elements, then you're looking for the in keyword:
if number in (1, 2, 3):
# Do logic
The or operator takes two arguments, on its left and right sides, and performs the following logic:
Evaluate the stuff on the left-hand side.
If it is a truthy value (e.g, bool(x) is True, so it's not zero, an empty string, or None), return it and stop.
Otherwise, evaluate the stuff on the right-hand side and return that.
As such, 1 or 2 or 3 is simply 1, so your expression turns into:
if number == (1):
If you actually mean number == 1 or number == 2 or number == 3, or number in (1, 2, 3), you'll need to say that.
(Incidentally: The and operator works the same way, except step 2 returns if the left-hand-side is falsey.)