how do I reference first argument of an enumeration? - python

I am writing code with enumerate() in Python, and I am having issues with referencing the first argument in enumerate:
For example, let nums be temperatures of different days:
nums = [1,5,20,9,3,10,50,7]
array = []
for j, distance in enumerate(nums):
for k, distance2 in enumerate(nums[1:],1):
if nums[j] < nums[k]:
array.append(distance2[j]-distance[k])
So, the challenge I have is: how do I reference the 'distance' and 'distance2' of each element respectively in my enumerations?
The aim of the problem is to determine for each day, how many days you'll have to wait for a warmer day, so for the example above, the output would be [1,1,4,3,1,1,0,0]; where there are no warmer days ahead, return 0.
Thanks

You need to calculate the distance based off the indexes not the values at the index.
You should not restart your subscript and inner index at 1 each time but rather at i each iteration.
nums = [1, 5, 20, 9, 3, 10, 50, 7]
array = []
for i, curr_temp in enumerate(nums):
days = 0
for j, future_temp in enumerate(nums[i:], i):
if curr_temp < future_temp:
# Set Days to Distance between Indexes
days = j - i
# Stop Looking Once Higher Value Found
break
array.append(days)
print(array)
Output:
[1, 1, 4, 2, 1, 1, 0, 0]

Related

How I can optimize the given below my python code?

I have an array and given an array of size N containing positive integers and I want to count number of smaller elements on right side of each array.
for example:-
Input:
N = 7
arr[] = {12, 1, 2, 3, 0, 11, 4}
Output: 6 1 1 1 0 1 0
Explanation: There are 6 elements right
after 12. There are 1 element right after
1. And so on.
And my code for this problem is like as :-
# python code here
n=int(input())
arr=list(map(int,input().split()))
ans=0
ANS=[]
for i in range(n-1):
for j in range(i+1,n):
if arr[i]>arr[j]:
ans+=1
ANS.append(ans)
ans=0
ANS.append(0)
print(ANS)
but the above my code take O(n^2) time complexity and I want to reduce the this. If anyone have any idea to reduce above python code time complexity please help me. Thank you.
This solution is O(n log(n)) as it is three iterations over the values and one sorting.
arr = [12, 1, 2, 3, 0, 11, 4]
# Gather original index and values
tups = []
for origin_index, el in enumerate(arr):
tups.append([origin_index, el])
# sort on value
tups.sort(key=lambda t: t[1])
res = []
for sorted_index, values in enumerate(tups):
# check the difference between the sorted and original index
# If there is a positive value we have the n difference smaller
# values to the right of this index value.
if sorted_index - values[0] > 0:
res.append([values[0], (sorted_index - values[0])])
elif sorted_index - values[0] == 0:
res.append([values[0], (sorted_index - values[0]) + 1])
else:
res.append([values[0], 0])
origin_sort_res = [0 for i in range(len(arr))]
for v in res:
# Return the from the sorted array to the original indexing
origin_sort_res[v[0]] = v[1]
print(origin_sort_res)
try this(nlog2n)
def solution(nums):
sortns = []
res = []
for n in reversed(nums):
idx = bisect.bisect_left(sortns, n)
res.append(idx)
sortns.insert(idx,n)
return res[::-1]
print(solution([12, 1, 2, 3, 0, 11, 4]))
# [6, 1, 1, 1, 0, 1, 0]

How can I get the index of max values in list and then print the values from another list with max's index?

d=[1,2,3,4,5,6,7]
g=[1,2,3,100,4,5,100]
m=max(g)
ll=[i for i, j in enumerate(g) if j == m]
print("The longest event time is",m,"for the event(s):",d[*ll])
I need to print after events the index of maximum values in d list
Such that , (The longest event time is 100 for the event(s):4 7
you can simply create a function to find the max and index of max in a list and return the corresponding value of the same index in a second list. here's the code :
# creating a function to get the index of Max in list A and return the corresponding value of the same index in list B
def get_id_max(first_list, second_list):
# Finding the max, and then it's index in the first list
global max_value
global max_index
max_value = max(first_list)
max_index = first_list.index(max_value)
# Return the corresponding value in the second list
return second_list[max_index]
# Defining A, B, and C
A = [2011,2012,2013,2014,2015]
B = [50, 60, 15, 76, 55]
C = [1.25, 2.2, 0.5, 1, 15]
print(f"The maximum value is {get_id_max(B,A)} and it's corresponding index is {max_index}")
# The maximum value is 2014 and it's corresponding index is 3
print(f"The maximum value is {get_id_max(C,A)} and it's corresponding index and value are {max_index,max_value}")
# The maximum value is 2015 and it's corresponding index and value are (4, 15)
events = [1, 2, 3, 4, 5, 6, 7]
durations = [1, 2, 3, 100, 4, 5, 100]
max_duration = max(durations)
longest_events = (str(event) for event, duration in zip(events, durations)
if duration == max_duration)
print(f"The longest event time is {max_duration}, for the event(s): {','.join(longest_events)}")
Your current approach requires several passes on the list. This is not the most optimal.
Here is an algorithm to compute the maxima in only one pass. It is similar to the classical manual computation of a maximum except it handles all maxima and the fact that the maximum is computed one one list, but the saved value is from another list (using zip)
m = float ('-inf')
out = [] # optional if -inf is not a possible value
for a,b in zip(d,g):
if b>m:
out = [a]
m=b
elif b == m:
out.append(a)
print(out)
Output: [4, 7]
Alternative without zip:
m = float ('-inf')
out = [] # optional if -inf is not a possible value
for i,b in enumerate(g):
if b>m:
out = [d[i]]
m=b
elif b == m:
out.append(d[i])
You can solve this with a little list comprehension:
vals = [dat[0] for dat in zip(d, g) if dat[1] == max(g)]
print(f"The longest event times are {max(g)}, for the event(s): {vals}")

Doing a 2sum algorithm and I'm confused on python syntax

so I followed a tutorial to learn how to complete 2 sum and I understand what ever line means but I dont understand why diffs[list[i]] returns the 0 index. I went through the the algorithm with the current arguments and i comes out to 3 when it returns the indexes
diffs = {} # Make a hash map to store values
for i in range(len(list)): # Iterate through list
if list[i] in diffs: # If the number you are on is in the has map
return [diffs[list[i]], i] # return indexes
else:
diffs[target - list[i]] = i
print(twosum([2, 11, 15, 7], 9))
def twosum(nums, target):
diffs = {} # Make a hash map to store values
for i in range(len(nums)): # Iterate through list
if nums[i] in diffs: # If the number you are on is in the has map
return [diffs[nums[i]], i] # return indexes
else:
diffs[target - nums[i]] = i
print(i, diffs)
In [4]: print(twosum([2, 11, 15, 7], 9))
0 {7: 0}
1 {7: 0, -2: 1}
2 {7: 0, -2: 1, -6: 2}
[0, 3]
As you can see from the above output, 7 has index 0 in the dictionary. It's the first element that is added to the dictionary. The reason is that you are saving the differences in the dictionary. target - nums[0] is 7 in this case because nums[0] is 2.
Then, when you reach the last element, namely 7, you find it in the dictionary with the index 0. That is diffs[nums[3]] == diffs[7] == 0. And you return [diffs[nums[i]], i] == [diffs[nums[3]], 3] == [diffs[7], 3] == [0, 3].
Also, don't use the name list to name your variables.
On the first run of the loop. diffs[target - list[i]] = i sets diffs to {7: 0}. That's how diffs[list[3]] evaluates to 0. Eg.
diffs[list[3]]
diffs[7]
0

How to count pair of peaks indexes including last entry?

I have hit a roadblock trying to include the last entry of an index to the output.
A pair of peaks is defined by a set of neighbouring values in a list that is higher than 3.
How can I include the index of the last entry into the output?
data_series_1 = [6,4,5,2,2,0,5,4,4,2,0,2,2,1,4,2,2,5,4,6]
def paired_peaks(data_series,threshold):
peaks =[]
for k in range(0,len(data_series)-1):
y_b = data_series[k-1]
y= data_series[k]
y_a = data_series[k+1]
if y>threshold:
if y_b>threshold or y_a>threshold:
peaks.append(k)
return peaks
print(paired_peaks(data_series_1,3))
I expected it to be [0, 1, 2, 6, 7, 8, 17, 18, 19], however the actual output is [0, 1, 2, 6, 7, 8, 17, 18].
Your problem happens when for loops comes to the end. When you get to the last element, you are trying to read the element that comes after it, and the element does not exist.
What might tricked you is because data_series[-1] actually read the last element instead of rising error.
Now, I don't know what your intentions are with your program, do you want to read the first element instead of nonexistant element? I assumed you do because first element is compared to the last and second one.
To fix your problem I did:
data_series_1 = [6,4,5,2,2,0,5,4,4,2,0,2,2,1,4,2,2,5,4,6]
def paired_peaks(data_series,threshold):
peaks =[]
l = len(data_series)
for k in range(l):
y_b = data_series[k-1]
y= data_series[k]
y_a = data_series[(k+1)%l]
if y > threshold:
if y_b > threshold or y_a > threshold:
peaks.append(k)
return peaks
print(paired_peaks(data_series_1,3))
I added wrote the length of data_series to variable l and then instead checked module value with data_series[(k+1)%l] to ensure your first element is read instead of nonexistant one.
This works as intended, however I advise you to check whether you want your first element to be compared to last element and do you want your last element be compared to the first element.
This would solve your problem:
data_series_1 = [6,4,5,2,2,0,5,4,4,2,0,2,2,1,4,2,2,5,4,6]
def paired_peaks(data_series,threshold):
peaks =[]
for k in range(len(data_series)):
y_b = data_series[k-1] if k - 1 in range(len(data_series)) else 0
y= data_series[k]
y_a = data_series[k+1] if k + 1 in range(len(data_series)) else 0
if y>threshold:
if y_b>threshold or y_a>threshold:
peaks.append(k)
return peaks
print(paired_peaks(data_series_1,3))
# returns: [0, 1, 2, 6, 7, 8, 17, 18, 19]
The reason your calculations stopped too early was because of: range(0,len(data_series)-1). You exited the loop to early. I also added if k +/- 1 in range(len(data_series)) else 0 to your code because the first item and last item of your list have no neighbour so it should be zero I assume. For the last item this would otherwise raise an Error because it's out of bounds. For the first item this didn't raise an error because data_series_1[-1] return the last item of your list, but I don't think that was intended in your code.

Using abs() in a list in Python

I am trying to create a list of integers and then scan it in order to find the minimum absolute value of the substractions of the elements of the list. I have created the list, but there is problem in the code which finds the minimum absolute value, as the result it shows is not correct. I think it is probably in the possitions of the elements of the list during the loops. Can you help me find it?
For example, when I create a list Α = [2, 7, 5, 9, 3, 1, 2], the result of min should be 0, but it is 1.
Here is my code:
min=1000
for i in range (1, N-1):
for j in range (i+1, N):
if (abs (A [i-1] - A [j-1])<min):
min = abs (A [i-1] - A [j-1])
print ("%d" %min)
You can do it like this:
A = [2, 7, 5, 9, 3, 1, 2]
temp = sorted(A)
min_diff = min([abs(i - j) for i, j in zip(temp [:-1], temp [1:])])
print(min_diff) # -> 0
Sorting makes sure that the element pair (i, j) which produce the overall smallest difference would be a pair of consecutive elements. That makes the
number of checks you have to perform much less than the brute force approach of all possible combinations.
Something a bit more clever that short-circuits:
A = [2, 7, 5, 9, 3, 1, 2]
def find_min_diff(my_list):
if len(set(my_list)) != len(my_list): # See note 1
return 0
else:
temp = sorted(my_list)
my_min = float('inf')
for i, j in zip(temp [:-1], temp [1:]):
diff = abs(i - j)
if diff < my_min:
my_min = diff
return my_min
print(find_min_diff(A)) # -> 0
Notes:
1: Converting to set removes the duplicates so if the corresponding set has less elements than the original list it means that there is at least one duplicate value. But that necessarily means that the min absolute difference is 0 and we do not have to look any further.
I would be willing to bet that this is the fastest approach for all lists that would return 0.
You should not be subtracting 1 from j in the inner loop as you end up skipping the comparison of the last 2. It is better to make the adjustments in the loop ranges, rather than subtracting 1 (or not) in the loop code:
A = [2, 7, 5, 9, 3, 1, 2]
N = 7
mint = 1000
for i in range (0, N-1):
for j in range (i+1, N):
if (abs(A[i] - A[j]) < mint):
mint = abs(A[i] - A[j])
print(i, j)
print(mint)
print(mint) # 0
I have also avoided the use of a built-in function name min.
To avoid the arbitrary, magic, number 1000, you can perform an initial check against None:
A = [2, 7, 5, 9, 3, 1, 2]
N = 7
mint = None
for i in range (0, N-1):
for j in range (i+1, N):
if mint is None:
mint = abs(A[i] - A[j])
elif (abs(A[i] - A[j]) < mint):
mint = abs(A[i] - A[j])
print(i, j)
print(mint)
print(mint) # 0
This is a brute-force solution:
from itertools import combinations
A = [2, 7, 5, 9, 3, 1, 2]
min(abs(i-j) for i, j in combinations(A, 2)) # 0
using numpy
import numpy as np
A = [2, 7, 5, 9, 3, 1, 2]
v = np.abs(np.diff(np.sort(np.array(A))))
np.min(v)
out : 0
Or You can use numpy only for the diff part like this :
v = min(abs(np.diff(sorted(A))))
This is what you are looking for:
A = [2, 7, 5, 9, 3, 1, 2]
diffs = []
for index1, i in enumerate(A):
for index2, j in enumerate(A):
if index1 != index2:
diffs.append(abs(i-j))
print(min(diffs))
Output:
0
Updated to exclude subtraction of same items

Categories