Related
This is a program that I recently made. The goal of this code is to a pair of corresponding lists. So randomStringpt1[0] corresponds to randomStringpt2[0]. I want to compare randomStringpt1[0] and randomString2[0] to the rest of the pairs that the user gave in the randomStrings. But after using this code, it looks like I have duplicated each pair many times, which is the opposite of what I was looking for. I was thinking of using a dictionary, but then realized that a dictionary key could only have one value, which wouldn't help my case if the user used a number twice. Does anyone know how I can reduce the duplicates?
(The tests I have been running have been with the numbers randomStringpt1 = [1,3,1,1,3] and randomStringpy2 = [2,4,2,3,4]
)
randomStringpt1 = [1, 2, 3, 4, 5] #Pair of strings that correspond to each other("1,2,3,4,5" doesn't actually matter)
randomStringpt2 = [1, 2, 3, 4, 5]
for i in range(len(randomStringpt1)):
randomStringpt1[i] = input("Values for the first string: ")
randomStringpt2[i] = input("Corresponding value for the second string: ")
print(randomStringpt1) #numbers that the user chose for the first number of the pair
print(randomStringpt2) #numbers that the user chose for the second number of the pair
newStart = []
newEnd = []
for num1 in range(len(randomStringpt1)):
for num2 in range(len(randomStringpt1)):
if (int(randomStringpt1[num1]) != int(randomStringpt1[num2]) and int(randomStringpt2[num1]) != int(randomStringpt2[num2])):
newStart.append(randomStringpt1[num1]) # Adding the pairs that aren't equal to each other to a new list
newEnd.append(randomStringpt2[num1])
newStart.append(randomStringpt1[num2])
newEnd.append(randomStringpt2[num2])
# else:
# print("The set of numbers from the randomStrings of num1 are not equal to the ones in num2")
print(newStart)
print(newEnd)
First let's analyze the 2 bugs in your code,
the if condition inside the loop is true every time a pair compares to a different one. this means for your example it should output
[1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 3]
[2, 2, 4, 4, 4, 2, 2, 3, 3, 4, 4, 4]
since you compare every pair to any other pair that exists. But your output is different because you append both pairs every time and getting a very big result, so you shouldn't append the num2 pairs.
Now, from what you described that you want, you should loop every pair and check if it already exists in the output list. So the for loop part can change like this
filtered = []
for pair in zip(randomStringpt1,randomStringpt2):
if pair not in filtered:
filtered.append(pair) # Adding the pairs that aren't equal to each other to a new list
the zip function takes the 2 lists and for every loop it returns 2 values one from each list the first value pair, then the second values and goes on. the filtered list will be in the following format [(1, 2), (3, 4), (1, 3)]
Alternative it can be as a one liner like this:
filtered = list(dict.fromkeys(zip(randomStringpt1, randomStringpt2)))
using the dictionary to identify unique elements and then turn it back into a list
after all that you can get the original format of the lists you had in your code by splitting them like this
newStart = [pair[0] for pair in filtered]
newEnd = [pair[1] for pair in filtered]
Finally i should tell you to read a little more on python and it's for loops, since the range(len(yourlist)) is not the python intended way to loop over lists, as python for loops are equivalent to for each loops on other languages and iterate over the list for you instead on relying in a value to get list elements like yourlist[value].
Given a sorted list [1,2,3,4,5,6,7,8] and a shuffled version of that list
a=[1,2,5,3,7,8,6,4]
I want to find how many steps each element has moved from its position relative to the sorted list (steps towards index 0 being positive, steps away from index 0 being negative) and store those step values in the respective index in a different list.
For the given input, the expected output is:
b=[0,0,-1,-4,2,-1,2,2]
Considering the value 3 (which is at index 2 in the sorted list), in the shuffled array it is at index 3, so it has taken -1 step, and hence b[2] = -1. Similarly for the value 8 (which is at index 7 in the sorted list), in the shuffled array it is at index 5, so it has taken +2 steps, and hence b[7] = 2.
This is what I have tried:
b=[0,0,0,0,0,0,0,0]
a=[1,2,5,3,7,8,6,4]
for x in range(len(a)):
b[a[x]]=a[x]-(x+1)
I am getting an error with this code:
IndexError: list assignment index out of range
Please help me understand this. Why can't I pass an integer from a list as an index to another list?
You can get the result you want with a simple comparison of the expected value at an array position with the index of that value in the a array. By iterating over the number of elements in a, we can generate the output array:
a = [1,2,5,3,7,8,6,4]
b = []
for x in range(len(a)):
b.append(x - a.index(x+1))
print(b)
Output
[0, 0, -1, -4, 2, -1, 2, 2]
Demo on rextester
The problem as you very well know is that there is an index error.
a=[1,2,5,3,7,8,6,4]
The above array has size = 8.
Now you create b:
b=[0,0,0,0,0,0,0,0]
The size of the list b is also 8.
In your for loop you are doing:
b[a[x]]
Pause...
If x is 5, then a[x] will be 8. However, there is no such thing as index 8 in list b, which only has up to index 7.
This is the problem.
You should change the code in your for-loop to:
b[a[x] - 1]=a[x]-(x+1)
I would suggest you change your loop to this:
for x, n in enumerate(a):
b[n-1] = n-(x+1)
Index starts from 0 to n-1
,so in b=[0,0,0,0,0,0,0,0] (having 8 elements) index will start from 0 to 7 and list 'a=[1,2,5,3,7,8,6,4]' contains numbers from 1-8 hence 8 is out of index.
corrected code:
b=[0,0,0,0,0,0,0,0]
a=[1,2,5,3,7,8,6,4]
for x in range(len(a)):
b[a[x] - 1]=a[x]-(x + 1)
Avoiding any indexing, nor unnecessary offsets, we can store the elements in a dictionary (the element as the key and its move as the value)
a=[1,2,5,3,7,8,6,4]
d = {v: v-e for e,v in enumerate(a, 1)}
b = [v for _, v in sorted(d.items())]
print(b)
produces
[0, 0, -1, -4, 2, -1, 2, 2]
I have the code below that gets the maximum value from a list. It then compares it to the maximum value of the remaining values in the list, and if it is more than 1 higher than the next greatest value, it replaces the original list maximum with 1 higher than the next greatest value. I would like the code to search the entire list and make sure that any value in the list is at most 1 larger than any other value in the list. I know this ins’t the best worded explanation, I hope the example lists below make what I’m trying to accomplish clearer.
for example I don’t want to get a final list like:
[0,2,0,3]
I would want the final list to be
[0,1,0,2]
input:
empt=[0,2,0,0]
Code:
nwEmpt=[i for i in empt if i !=max(empt)]
nwEmpt2=[]
for i in range(0,len(empt)):
if (empt[i]==max(empt))&(max(empt)>(max(nwEmpt)+1)):
nwEmpt2.append((max(nwEmpt)+1))
elif (empt[i]==max(empt))&(max(empt)==(max(nwEmpt)+1)):
nwEmpt2.append(max(empt))
else:
nwEmpt2.append(empt[i])
output:
nwEmpt2
[0,1,0,0]
min_value = min(empt)
empt_set = set(empt)
for i in empt:
nwEmpt.append(min_value + len(list(filter(lambda x: x < i, empt_set))))
This gives e.g. for input empt = [8, 10, 6, 4, 4] output nwEmpt = [6, 7, 5, 4, 4].
It works by mapping each element to (the minimum value) + (the number of distinct values smaller than element).
I have an arbitrary data set, given in the form of nested lists. I wish to replace all values in my data > 0 with 1, to create a sort of binary array. Similar to normalizing.
I'm imagining this is best done with a for loop. I tried using enumerate but got confused working with enumerate types.
For example:
test = [[5,5,0,0,5],[0,0,0,0,5]]
for i in range(len(test)):
for j in range(len(test[i])):
if j > 0:
test[i][j] = 1
I'd expect:
[[1,1,0,0,1],[0,0,0,0,1]]
but instead got:
[[5, 1, 1, 1, 1], [0, 1, 1, 1, 1]]
Any help would be appreciated.
Since you need the values > 0 to be replaced, the condition should be as follows. Checking j > 0 would mean all nested list values except the first one would be set to 1.
test = [[5,5,0,0,5],[0,0,0,0,5]]
for i in range(len(test)):
for j in range(len(test[i])):
if test[i][j] > 0:
test[i][j] = 1
I have some code that performs the following operation, however I was wondering if there was a more efficient and understandable way to do this. I am thinking that there might be something in itertools or such that might be designed to perform this type of operation.
So I have a list of integers the represents changes in the number of items from one period to the next.
x = [0, 1, 2, 1, 3, 1, 1]
Then I need a function to create a second list that accumulates the total number of items from one period to the next. This is like an accumulate function, but with elements from another list instead of from the same list.
So I can start off with an initial value y = 3.
The first value in the list y = [3]. The I would take the second
element in x and add it to the list, so that means 3+1 = 4. Note that I take the second element because we already know the first element of y. So the updated value of y is [3, 4]. Then the next iteration is 4+2 = 6. And so forth.
The code that I have looks like this:
def func():
x = [0, 1, 2, 1, 3, 1, 1]
y = [3]
for k,v in enumerate(x):
y.append(y[i] + x[i])
return y
Any ideas?
If I understand you correctly, you do what what itertools.accumulate does, but you want to add an initial value too. You can do that pretty easily in a couple ways.
The easiest might be to simply write a list comprehension around the accumulate call, adding the initial value to each output item:
y = [3 + val for val in itertools.accumulate(x)]
Another option would be to prefix the x list with the initial value, then skip it when accumulate includes it as the first value in the output:
acc = itertools.accumulate([3] + x)
next(acc) # discard the extra 3 at the start of the output.
y = list(acc)
Two things I think that need to be fixed:
1st the condition for the for loop. I'm not sure where you are getting the k,v from, maybe you got an example using zip (which allows you to iterate through 2 lists at once), but in any case, you want to iterate through lists x and y using their index, one approach is:
for i in range(len(x)):
2nd, using the first append as an example, since you are adding the 2nd element (index 1) of x to the 1st element (index 0) of y, you want to use a staggered approach with your indices. This will also lead to revising the for loop condition above (I'm trying to go through this step by step) since the first element of x (0) will not be getting used:
for i in range(1, len(x)):
That change will keep you from getting an index out of range error. Next for the staggered add:
for i in range(1, len(x)):
y.append(y[i-1] + x[i])
return y
So going back to the first append example. The for loop starts at index 1 where x = 1, and y has no value. To create a value for y[1] you append the sum of y at index 0 to x at index 1 giving you 4. The loop continues until you've exhausted the values in x, returning accumulated values in list y.